Monad facade for a MonadState in Haskell - haskell

Background: I'm creating a game with a stateful monad for reading and writing changes to the global state of the game.
I would like to divide my game into components, such as "Characters", providing a domain specific way for these components to interact with the global state. Ideally this might be define specific actions of the form MonadState Character m => m a that I could use, but each such m a would enact changes on the parent (global state).
I've searched around for converting between state monads, or providing an interface from one state monad to another, but the specific language for this is beyond my scope of knowledge. I am also already using Lenses, and I'm wondering if I can do something with them.
EDIT:
I'd like to be able to do something like
moveCharacter :: MonadState Character m => Int -> Int -> m ()
and have that perform move :: MonadState World m => Int -> Int -> m () inside. Basically, abstracting the world specifics away from the character.
Thanks!

Sounds like you're looking for Zoom, which lets you convert a stateful action on the view of a lens into a stateful action on the source of the lens.

You actually need 2 conversion functions: one to extract the character from the world and another one to modify the world with the modified character. You can put them together like this:
extractCharacter :: World -> Character
extractCharacter = error "Tried to call placeholder function"
replaceCharacter :: World -> Character -> World
replaceCharacter = error "Tried to call placeholder function"
runCharacterSubroutine :: (Functor m) =>
StateT Character m a -> StateT World m a
runCharacterSubroutine act = StateT $ \w ->
fmap (\(a,c') -> (a,replaceCharacter w c')) $
runStateT act (extractCharacter w)
In your game, you probably want something a little more complicated, but that's just a matter of adding an extra parameter to extractCharacter and replaceCharacter
Note that the function I gave only works if the StateT is at the top of the monad transformer stack. If it's not: you will have to use the mmorph package

Related

What's the difference between view and use in lens?

What's the difference between
view :: MonadReader s m => Getting a s a -> m a
and
use :: MonadState s m => Getting a s a -> m a
in Control.Lens.Getter?
Taking a look at the type signatures, view takes a MonadReader (such as ReaderT) and use takes a MonadState (such as StateT). Now, view and use both have the same objective: extract a reasonable value from the thing we're looking at.
MonadReader represents read-only state. We can access the value within using ask. MonadState represents read-write state, which can be retrieved with get. So both view and use query the internal state of the monad given, but view calls ask whereas use calls get. Generally speaking, only one will be applicable to your situation.
A look at the source code for the two functions is not particularly enlightening unless you already understand how lenses are implemented (and if you do, then you probably understand the difference between view and use), so this is a good example of a situation where the type signatures can be much more enlightening than the code itself.
A lens getter gives us a function from its source to its target:
(^.) :: s -> Getting a s a -> a
flip (^.) :: Getting a s a -> s -> a
Any function can be made into a MonadReader computation, with the argument type of the function as the environment type:
asks :: MonadReader s m => (s -> a) -> m a
That being so, (^.) can be generalised to any MonadReader through asks, giving rise to view:
view :: MonadReader s m => Getting a s a -> m a
view g = asks (\s -> s ^. g)
(The definitions I'm using here aren't literally the ones you will find in the Control.Lens.Getter source, but they are equivalent to them as far as results go.)
In a similar way, any function can be made into a MonadState computation that leaves the state unchanged, with the argument type of the function as the state type:
gets :: MonadState s m => (s -> a) -> m a
Accordingly, (^.) can also be generalised to any MonadState through gets, resulting in use:
use :: MonadReader s m => Getting a s a -> m a
use g = gets (\s -> s ^. g)
From another angle, view and use can be seen as variants of asks and gets, respectively, that take a getter as argument, rather than a function directly.
On a final note about view, functions themselves are instances of MonadReader. That being so, view can be used as a prefix/non-operator version of (^.).

Why is the output of this Haskell function an IO String instead of a String

I'm learning Haskell through learnyouahaskell.com and wanted to test some of the concepts before finishing the input/output module. I haven't been able to google or hoogle my way out of this question, though, even though it seems quite simple.
When I try to run the following code
getName = do
name <- getLine
return name
the output of getName becomes an element of type IO String instead of String, even though name is definitely a String
By reading the documentation and other StackVverflow's questions I couldn't figure out why is this happening when I declare getName as a function (when I use the bind <- operation directly on main there's no problem whatsoever).
The return function is not conceptually the same as what return does in languages like C++, Java and Python. return :: Monad m => a -> m a takes an a (here a String), and produces an m a (here IO a).
The do notation is syntacticual sugar. If we desugar the statement, you wrote:
getName = getLine >>= (\name -> return name)
or cleaner:
getName = getLine >>= return
The bind function (>>=) :: Monad m => m a -> (a -> m b) -> m b thus has as first operand an m a, and as second a function a -> m b, and produces an m b. Since getLine :: IO String is an IO String, that thus means that m is the same as IO, and a is the same as String. The return :: Monad m => a -> m a, makes it clear that here b is the same as a.
Then what is IO here. A metaphor that is frequently used is the one of a recipe. In this metaphor an IO a is a set of instructions that when you follow these, you will get an a. But that does not mean that that recipe is an a.
(>>=) here basically says that, on the left hand I have a recipe to make a, on the right hand I have a function that converts that a into a recipe to make b, so we can construct a recipe to make b with these two.
People often ask how to unwrap an a out of an IO a, but conceptually it makes not much sense. You can not "unwrap" the cake out of a recipe to make a cake. You can follow the instructions to make a cake. Following instructions is something the main will eventually do. We thus can construct a (long) recipe the main will do. But we can not unwrap the values.
Strictly speaking there is a function unsafePerformIO :: IO a -> a that can do that. But it is strongly adviced not to use that. Functions in Haskell are supposed to be pure that means that for the same input, we always retrieve the same output. getLine itself is a pure, since it always produces the same recipe (IO String).

Type Variable Location in Transformers

Consider the State type - or at least a simplified version:
newtype State s a = State { runState :: s -> (a, s) }
Now, let's say we want to derive the StateT monad transformer. transformers defines it as follows:
newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }
Here, the m has been placed on the right of the function arrow, but outside the tuple. However, if we didn't know the correct answer, we might instead put m somewhere else:
newtype StateT s m a = StateT { runStateT :: m (s -> ( a, s)) }
newtype StateT s m a = StateT { runStateT :: s -> (m a, s) }
Obviously the version in transformers is correct, but why? More generally, how does one know where to put the type variable for the 'inner' monad when defining a monad transformer? Generalising even more, is there a similar rule for comonad transformers?
I think the difference can be easily understood when m ~ IO:
s -> IO (a, s)
is the type of an action which can read the current state s, perform IO depending on that (e.g. printing the current state, reading a line from the user), and then produce both the new state s, and a return value a.
Instead:
IO (s -> (a, s))
is the type of an action which immediately performs IO, without knowing the current state. After all the IO is over, it returns a pure function mapping the old state into a new state and a return value.
This is similar to the previous type, since the new state and return value can depend both on the previous state and the IO. However, the IO can not depend on the current state: e.g., printing the current state is disallowed.
Instead,
s -> (IO a, s)
is the type of an action which reads the current state s, and then performs IO depending on that (e.g. printing the current state, reading a line from the user), and then produce a return value a. Depdnding on the current state, bot not on the IO, a new state is produced. This type is effectively isomorphic to a pair of functions (s -> IO a, s -> s).
Here, the IO can read a line from the user, and produce a return value a depending on that, but the new state can not depend on that line.
Since the first variant is more general, we want that as our state transformer.
I don't think there's a "general rule" for deciding where to put m: it depends on what we want to achieve.

How to modify parts of a State in Haskell

I have a number of operations which modify a System. System is defined like this:
data System = Sys {
sysId :: Int,
sysRand :: StdGen,
sysProcesses :: ProcessDb,
sysItems :: ItemDb
}
with e.g.
type ProcessDb = M.Map Int Process
But I also have some functions, which do not need access to the full System, but have types like this:
foo' :: (Process, ItemDb) -> ((Process, ItemDb),[Event])
Currently I gave them types like
foo: System -> (System, [Event])
But this is a needlessly broad interface. To use the narrow interface above in conjuntion with System I would have to extract a single Process and the ItemDb from System, run foo' and then modify System with the results.
This is quite some unwrapping and wrapping and results in more lines of code than just passing system as a whole and let foo extract whatever it needs. In the latter case, the wrapping and unwrapping is mingled with the actual foo' operation and I have the feeling that these two aspects should be separated.
I suppose I need some kind of lifting operation which turns a narrow foo' into a foo. I suppose I could write this, but I would have to write such a lifter for every signature of the narrow functions, resulting is lots of different lifters.
is there an idiom how to solve such problems?
is it worth bothering?
One common solution is to use a class, possibly created by the Template Haskell magic of Control.Lens.TH.makeClassy. The gist is that you pass in the whole System, but you don't let the function know that that's what you're giving it. All it's allowed to know is that what you're giving it offers methods for getting and/or modifying the pieces it's supposed to handle.
I ended up writing a function which work on any State and which requires a "Lens" which captures the specfic transformation from the bigger State to the smaller State and back
focus :: (Lens s' s) -> State s' a -> State s a
focus lens ms'= do
s <- get
let (s', set) = lens s
(a, s'') = runState ms' s'
put (set s'')
return a
It allows me to write things like
run :: ExitP -> State SimState Log
...
do
evqs' <-focus onSys $ step (t,evt)
...
Where step operates on the "smaller" state
step :: Timed Event -> State Sys.System [EventQu]
Here onSys is a "Lens" and it works like this:
onSys :: Lens Sys.System SimState
onSys (Sis e s) = (s, Sis e)
where
data SimState = Sis {
events :: EventQu,
sisSys :: Sys.System
I suppose the existing Lens libraries follow a similar approach, but do much more magic, like creating lenses automatically. I did shy away from lenses. Instead I was pleased to realise that all it takes was a few lines of codes to get what I need.

What general structure does this type have?

While hacking something up earlier, I created the following code:
newtype Callback a = Callback { unCallback :: a -> IO (Callback a) }
liftCallback :: (a -> IO ()) -> Callback a
liftCallback f = let cb = Callback $ \x -> (f x >> return cb) in cb
runCallback :: Callback a -> IO (a -> IO ())
runCallback cb =
do ref <- newIORef cb
return $ \x -> readIORef ref >>= ($ x) . unCallback >>= writeIORef ref
Callback a represents a function that handles some data and returns a new callback that should be used for the next notification. A callback which can basically replace itself, so to speak. liftCallback just lifts a normal function to my type, while runCallback uses an IORef to convert a Callback to a simple function.
The general structure of the type is:
data T m a = T (a -> m (T m a))
It looks much like this could be isomorphic to some well-known mathematical structure from category theory.
But what is it? Is it a monad or something? An applicative functor? A transformed monad? An arrow, even? Is there a search engine similar Hoogle that lets me search for general patterns like this?
The term you are looking for is free monad transformer. The best place to learn how these work is to read the "Coroutine Pipelines" article in issue 19 of The Monad Reader. Mario Blazevic gives a very lucid description of how this type works, except he calls it the "Coroutine" type.
I wrote up his type in the transformers-free package and then it got merged into the free package, which is its new official home.
Your Callback type is isomorphic to:
type Callback a = forall r . FreeT ((->) a) IO r
To understand free monad transformers, you need to first understand free monads, which are just abstract syntax trees. You give the free monad a functor which defines a single step in the syntax tree, and then it creates a Monad from that Functor that is basically a list of those types of steps. So if you had:
Free ((->) a) r
That would be a syntax tree that accepts zero or more as as input and then returns a value r.
However, usually we want to embed effects or make the next step of the syntax tree dependent on some effect. To do that, we simply promote our free monad to a free monad transformer, which interleaves the base monad between syntax tree steps. In the case of your Callback type, you are interleaving IO in between each input step, so your base monad is IO:
FreeT ((->) a) IO r
The nice thing about free monads is that they are automatically monads for any functor, so we can take advantage of this to use do notation to assemble our syntax tree. For example, I can define an await command that will bind the input within the monad:
import Control.Monad.Trans.Free
await :: (Monad m) => FreeT ((->) a) m a
await = liftF id
Now I have a DSL for writing Callbacks:
import Control.Monad
import Control.Monad.Trans.Free
printer :: (Show a) => FreeT ((->) a) IO r
printer = forever $ do
a <- await
lift $ print a
Notice that I never had to define the necessary Monad instance. Both FreeT f and Free f are automatically Monads for any functor f, and in this case ((->) a) is our functor, so it automatically does the right thing. That's the magic of category theory!
Also, we never had to define a MonadTrans instance in order to use lift. FreeT f is automatically a monad transformer, given any functor f, so it took care of that for us, too.
Our printer is a suitable Callback, so we can feed it values just by deconstructing the free monad transformer:
feed :: [a] -> FreeT ((->) a) IO r -> IO ()
feed as callback = do
x <- runFreeT callback
case x of
Pure _ -> return ()
Free k -> case as of
[] -> return ()
b:bs -> feed bs (k b)
The actual printing occurs when we bind runFreeT callback, which then gives us the next step in the syntax tree, which we feed the next element of the list.
Let's try it:
>>> feed [1..5] printer
1
2
3
4
5
However, you don't even need to write all this up yourself. As Petr pointed out, my pipes library abstracts common streaming patterns like this for you. Your callback is just:
forall r . Consumer a IO r
The way we'd define printer using pipes is:
printer = forever $ do
a <- await
lift $ print a
... and we can feed it a list of values like so:
>>> runEffect $ each [1..5] >-> printer
1
2
3
4
5
I designed pipes to encompass a very large range of streaming abstractions like these in such a way that you can always use do notation to build each streaming component. pipes also comes with a wide variety of elegant solutions for things like state and error handling, and bidirectional flow of information, so if you formulate your Callback abstraction in terms of pipes, you tap into a ton of useful machinery for free.
If you want to learn more about pipes, I recommend you read the tutorial.
The general structure of the type looks to me like
data T (~>) a = T (a ~> T (~>) a)
where (~>) = Kleisli m in your terms (an arrow).
Callback itself doesn't look like an instance of any standard Haskell typeclass I can think of, but it is a Contravariant Functor (also known as Cofunctor, misleadingly as it turns out). As it is not included in any of the libraries that come with GHC, there exist several definitions of it on Hackage (use this one), but they all look something like this:
class Contravariant f where
contramap :: (b -> a) -> f a -> f b
-- c.f. fmap :: (a -> b) -> f a -> f b
Then
instance Contravariant Callback where
contramap f (Callback k) = Callback ((fmap . liftM . contramap) f (f . k))
Is there some more exotic structure from category theory that Callback possesses? I don't know.
I think that this type is very close to what I have heard called a 'Circuit', which is a type of arrow. Ignoring for a moment the IO part (as we can have this just by transforming a Kliesli arrow) the circuit transformer is:
newtype CircuitT a b c = CircuitT { unCircuitT :: a b (c, CircuitT a b c) }
This is basicall an arrow that returns a new arrow to use for the next input each time. All of the common arrow classes (including loop) can be implemented for this arrow transformer as long as the base arrow supports them. Now, all we have to do to make it notionally the same as the type you mention is to get rid of that extra output. This is easily done, and so we find:
Callback a ~=~ CircuitT (Kleisli IO) a ()
As if we look at the right hand side:
CircuitT (Kleisli IO) a () ~=~
(Kliesli IO) a ((), CircuitT (Kleisli IO) a ()) ~=~
a -> IO ((), CircuitT (Kliesli IO) a ())
And from here, you can see how this is similar to Callback a, except we also output a unit value. As the unit value is in a tuple with something else anyway, this really doesn't tell us much, so I would say they're basically the same.
N.B. I used ~=~ for similar but not entirely equivalent to, for some reason. They are very closely similar though, in particular note that we could convert a Callback a into a CircuitT (Kleisli IO) a () and vice-versa.
EDIT: I would also fully agree with the ideas that this is A) a monadic costream (monadic operation expecitng an infinite number of values, I think this means) and B) a consume-only pipe (which is in many ways very similar to the circuit type with no output, or rather output set to (), as such a pipe could also have had output).
Just an observation, your type seems quite related to Consumer p a m appearing in the pipes library (and probably other similar librarties as well):
type Consumer p a = p () a () C
-- A Pipe that consumes values
-- Consumers never respond.
where C is an empty data type and p is an instance of Proxy type class. It consumes values of type a and never produces any (because its output type is empty).
For example, we could convert a Callback into a Consumer:
import Control.Proxy
import Control.Proxy.Synonym
newtype Callback m a = Callback { unCallback :: a -> m (Callback m a) }
-- No values produced, hence the polymorphic return type `r`.
-- We could replace `r` with `C` as well.
consumer :: (Proxy p, Monad m) => Callback m a -> () -> Consumer p a m r
consumer c () = runIdentityP (run c)
where
run (Callback c) = request () >>= lift . c >>= run
See the tutorial.
(This should have been rather a comment, but it's a bit too long.)

Resources