Haskell — Monad binding evaluation order - haskell

I'm having some trouble figuring out /how/ the bind operator would actually bind together the following State monads:
pop :: State [Int] Int
pop = do
(x:xs) <- get
put xs
return x
push :: Int -> State [Int] ()
push x = do
xs <- get
put (x:xs)
doStuff :: State [Int] ()
doStuff = do
pop
x <- pop
push 5
push x
Take doStuff, which can be desugared to the following:
pop >>= (\_ -> pop >>= (\x -> push 5 >>= (\_ -> push x)))
When this line is evaluated, in what order does the binding actually happen? Since, to actually bind, Haskell needs to get a State monad out of the function on the right of the >>= operator (i.e. the function right operands need to be fully evaluated first), I would've thought that the following would happen:
s1 = push 5 >>= (\_ -> push x)
s2 = pop >>= (\x -> s1)
s3 = pop >>= (\_ -> s2)
Is this the right way to think about it? I feel that I understand monads well, but my biggest problem is in actually visualising what's happening "behind the scenes" and how the data is flowing, so to speak. The do notation gives the illusion that I'm dealing with a bunch of sequential operations, when in fact, there's a whole bunch of nesting and closures.
I feel somewhat like I'm over-thinking things here and further confusing myself as a result.

Starting from
pop >>= (\_ -> pop >>= (\x -> push 5 >>= (\_ -> push x)))
a few functions can be inlined (to show what is happening better). I will start with (>>=), pretending that State is not defined as a transformer or newtype, to keep things simple.
type State s a = s -> (a, s)
m >>= k = \ s -> let (a, s') = m s in k a s'
\ s -> let (a, s') = pop s in
(\ _ -> pop >>= (\ x -> push 5 >>= (\ _ -> push x))) a s'
\ s -> let (_, s') = pop s in
(pop >>= (\ x -> push 5 >>= (\ _ -> push x))) s'
\ s -> let (_, s') = pop s in
let (a, s'') = pop s' in
(\ x -> push 5 >>= (\ _ -> push x)) a s''
\ s -> let (_, s') = pop s in
let (a, s'') = pop s' in
(push 5 >>= (\ _ -> push a)) s''
\ s -> let (_, s') = pop s in
let (a, s'') = pop s' in
let (b, s''') = push 5 s'' in
(\ _ -> push a)) b s'''
\ s -> let (_, s') = pop s in
let (a, s'') = pop s' in
let (_, s''') = push 5 s'' in
push a s'''

Is this the right way to think about it?
No.
First of all: while it is obviously correct to think of "first this happens, than that, then we evaluate this keyboard input..." in the IO monad, this isn't true for all monads. For instance, in the list monad this doesn't really make any sense. In general, it's not possible to assign a particular order to calculations in Haskell at all, it's not defined behaviour.
Yet, it is always possible, and very often helpful, to think of an order of computations in a monad, and this order is in fact the one suggested by the do notation. So, most of the time it isn't actually insightful to think about the desugared expression. But if you wish to make that step, here's how I'd do it:
pop >>= \_ -> THUNK1
THUNK1 ≡> pop >>= \x -> THUNK2
{Closure{x}} THUNK2 ≡> push 5 >>= \_ -> THUNK3
{Closure{x}} THUNK3 ≡> push x
Which is of course grotesquely more ugly, but says pretty much the same as the sugared do expression.

When this line is evaluated, in what order does the binding actually happen?
There's nothing special about "binding" here. The desugared expression is evaluated in exactly the same (lazy) way any other expression would be, and the specifics depend on the implementation of (>>=) for the particular monad you're working with.
If we're talking about using something like runState, given an expression like foo >>= (\x -> bar), the outermost expression is the application of (>>=) but we're trying to unwrap a newtype and then apply the function inside, so the (>>=) gets forced, as does the function.
If we consider instead the list monad, (>>=) is concatMap. Given an expression like [foo1, foo2] >>= (\x -> [bar1, bar2, x] >>= (\y -> [baz, y])), using take 5 on the result is clearly not going to fully compute all the binds.
That said, there is one important rule here: To whatever extent evaluating x >>= f forces the evaluation of x, in a large expression like a desugared do block the forcing will occur in the apparent "sequential" order, for the same reason that the "sequential illusion" is possible.

Related

Right-tightening ArrowLoop law

According to the Control.Arrow documentation, for many monads (those for which the >>= operation is strict) the instance MonadFix m => ArrowLoop (Kleisli m) does not satisfy the right-tightening law (loop (f >>> first h) = loop f >>> h) required by the ArrowLoop class. Why is that so?
This is multi-faceted question with several different angles, and it goes back to the value-recursion (mfix/mdo) in Haskell. See here for background information. I'll try to address the right-tightening issue here in some detail.
Right-tightening for mfix
Here's the right-tightening property for mfix:
mfix (λ(x, y). f x >>= λz. g z >>= λw. return (z, w))
= mfix f >>= λz. g z >>= λw. return (z, w)
Here it is in picture form:
The dotted-lines show where the "knot-tying" is happening. This is essentially the same law as mentioned in the question, except it is expressed in terms of mfix and value-recursion. As shown in Section 3.1 of this work, for a monad with a strict bind operator, you can always write an expression that distinguishes the left-hand side of this equation from the right hand-side, thus failing this property. (See below for an actual example in Haskell.)
When an arrow is created via the Kleisli construction from a monad with mfix, the corresponding loop operator fails the corresponding property in the same way.
Domain-theory and approximations
In domain theoretic terms, the mismatch will always be an approximation.
That is, the left hand-side will always be less defined than the right. (More precisely, the lhs will be lower than the rhs, in the domain of PCPOs, the typical domain we use for Haskell semantics.) In practice, this means that the right hand side will terminate more often, and is to be preferred when that is an issue. Again, see Section 3.1 of this for details.
In practice
This may sound all abstract, and in a certain sense it is. More intuitively, the left hand side gets a chance to act on the recursive value as it is being produced since g is inside the "loop," and thus is able to interfere with the fixed-point computation. Here's an actual Haskell program to illustrate:
import Control.Monad.Fix
f :: [Int] -> IO [Int]
f xs = return (1:xs)
g :: [Int] -> IO Int
g [x] = return x
g _ = return 1
lhs = mfix (\(x, y) -> f x >>= \z -> g z >>= \w -> return (z, w))
rhs = mfix f >>= \z -> g z >>= \w -> return (z, w)
If you evaluate the lhs it will never terminate, while rhs will give you the infinite list of 1's as expected:
*Main> :t lhs
lhs :: IO ([Int], Int)
*Main> lhs >>= \(xs, y) -> return (take 5 xs, y)
^CInterrupted.
*Main> rhs >>= \(xs, y) -> return (take 5 xs, y)
([1,1,1,1,1],1)
I interrupted the computation in the first case as it is non-terminating. While this is a contrived example, it is the simplest to illustrate the point. (See below for a rendering of this example using the mdo-notation, which might be easier to read.)
Example monads
Typical examples of monads that do not satisfy this law include Maybe, List, IO, or any other monad that's based on an algebraic type with multiple constructors. Typical examples of monads that do satisfy this law are State and Environment monads. See Section 4.10 for a table summarizing these results.
Pure-right shrinking
Note that a "weaker" form of right-tightening, where the function g in the above equation is pure, follows from value-recursion laws:
mfix (λ(x, y). f x >>= λz. return (z, h z))
= mfix f >>= λz. return (z, h z)
This is the same law as before with, g = return . h. That is g cannot perform any effects. In this case, there is no way to distinguish the left-hand side from the right as you might expect; and the result indeed follows from value-recursion axioms. (See Section 2.6.3 for a proof.) The picture in this case looks like this:
This property follows from the sliding property, which is a version of dinaturality for value-recursion, and is known to be satisfied by many monads of interest: Section 2.4.
Impact on the mdo-notation
The failure of this law has an impact on how the mdo notation was designed in GHC. The translation includes the so called "segmentation" step precisely to avoid the failure of the right-shrinking law. Some people consider that a bit controversial as GHC automatically picks the segments, essentially applying the right-tightening law. If explicit control is needed, GHC provides the rec keyword to leave the decision to the users.
Using the mdo-notation and explicit do rec, the above example renders
as follows:
{-# LANGUAGE RecursiveDo #-}
f :: [Int] -> IO [Int]
f xs = return (1:xs)
g :: [Int] -> IO Int
g [x] = return x
g _ = return 1
lhs :: IO ([Int], Int)
lhs = do rec x <- f x
w <- g x
return (x, w)
rhs :: IO ([Int], Int)
rhs = mdo x <- f x
w <- g x
return (x, w)
One might naively expect that lhs and rhs above should be the same, but due to the failure of the right-shrinking law, they are not. Just like before, lhs gets stuck, while rhs successfully produces the value:
*Main> lhs >>= \(x, y) -> return (take 5 x, y)
^CInterrupted.
*Main> rhs >>= \(x, y) -> return (take 5 x, y)
([1,1,1,1,1],1)
Visually inspecting the code, we see that the recursion is simply for the function f, which justifies the segmentation that is automatically performed by the mdo-notation.
If the rec notation is to be preferred, the programmer will need to put it in minimal blocks to ensure termination. For instance, the above expression for lhs should be written as follows:
lhs :: IO ([Int], Int)
lhs = do rec x <- f x
w <- g x
return (x, w)
The mdo-notation takes care of this and places the recursion over minimal blocks without user intervention.
Failure for Kleisli Arrows
After this lengthy detour, let us now go back to the original question about the corresponding law for arrows. Similar to the mfix case, we can construct a failing example for Kleisli arrows as well. In fact, the above example translates more or less directly:
{-# LANGUAGE Arrows #-}
import Control.Arrow
f :: Kleisli IO ([Int], [Int]) ([Int], [Int])
f = proc (_, ys) -> returnA -< (ys, 1:ys)
g :: Kleisli IO [Int] Int
g = proc xs -> case xs of
[x] -> returnA -< x
_ -> returnA -< 1
lhs, rhs :: Kleisli IO [Int] Int
lhs = loop (f >>> first g)
rhs = loop f >>> g
Just like in the case of mfix, we have:
*Main> runKleisli rhs []
1
*Main> runKleisli lhs []
^CInterrupted.
The failure of right-tightening for mfix of the IO-monad also prevents the Kleisli IO arrow from satisfying the right-tightening law in the ArrowLoop instance.

Understanding Monadic Fibonacci

I am learning haskell and learning monads. I've watched and read various tutorials and coded some simple examples for state monad, however I am not able to understand the following piece of code (taken from Haskell Wiki):
import Control.Monad.State
fib n = flip evalState (0,1) $ do
forM [0..(n-1)] $ \_ -> do
(a,b) <- get
put (b,a+b)
(a,b) <- get
return a
My question boils down to the following:
What is going inside the first statement of the inner do, i.e what does (a,b)<-get result into. What will be the values of a and b for some concrete example.
Why would you want to use the state monad over here?
In this example, the state is a pair containing the previous two numbers generated in the sequence. This is initially (0, 1) provided to evalState.
The type of get is MonadState s m => m s so in the inner do block
(a, b) <- get
fetches the state pair and binds a and b to the first and second elements respectively. The state is then updated in the following put.
The state will therefore be:
(0, 1), (1, 1), (1, 2), (3, 2), (3, 5), ...
The outer
(a, b) <- get
return a
unpacks the final state value and returns the first element.
First lets make clear the Fibonacci algorithm being used. The idea is to start with the tuple (0, 1), then find the next as (1, 0 + 1), the next as (1, 1 + 1), (2, 2 + 1), (3, 3 + 2), and so on. Generally, the step is \(a, b) -> (b, a + b). You can see that in these tuples are the Fibonacci numbers.
What is going inside the first statement of the inner do, i.e what
does (a,b)<-get result into?
Haskell does not have statements, only expressions.
y <- x is not a complete expression. It is similar to x >>= \y ->.
y <- x
m
Is a complete expression and is equivalent to x >>= \y -> m. A line n not of the form y <- n is equivalent to _ <- n (excluding let lines and maybe some others I forget).
Using this we can desugar do-notation.
fib n =
flip evalState (0, 1)
( forM
[0..(n-1)]
(\_ -> get >>= (\(a, b) -> put (b, a + b)))
>>= (\_ -> get >>= (\(a, b) -> return a)))
)
Now it is just about understanding >>=, return, get, put, and so on.
State is actually just functions of the type s -> (s, a). They take an initial state and yield the next state plus some other value.
m >>= n a.k.a. "bind" has the type Monad m => m a -> (a -> m b) -> m b. Then, if our Monad is State s, this is the same as:
m >>= n ::
( s -> (s, a))
-> (a -> s -> (s, b))
-> ( s -> (s, b))
The a returned by m has to be passed to n. What else can we guess? We expect the state to pass along as well, so the state returned by m must be passed to n as well. The function m >>= n must return the state and value that n returns. We then know how to implement bind:
m >>= n = uncurry (flip n) . m
return :: Monad m => a -> m a which is then equivalent to return :: a -> s -> (s, a):
return = flip (,)
get :: State s s is equivalent to get :: s -> (s, s):
get = join (,)
put :: s -> State s () or put :: s -> s -> (s, ()):
put s _ = (s, ())
evalState :: s -> State s a -> a or evalState :: s -> (s -> (s, a)) -> a:
evalState s f = snd (f s)
You can expand all the definitions and see exactly what is happening in the example. Just the intuitions should suffice though.
forM
[0..(n-1)]
(\_ -> get >>= (\(a, b) -> put (b, a + b)))
We don't care about having the numbers 0 to n - 1 so the first argument is dropped. get retrieves the current state, then put writes the new state. We do this n times.
>>= (\_ -> get >>= (\(a, b) -> return a)))
We don't care about the accumulated value (which is unit) and so the first parameter is dropped. Then we get the current state and project just the first element of the pair. This is the final answer we're looking for.
flip evalState (0, 1) …
Finally we run starting from the initial state (0, 1).
There are some cleanups we can make to this implementation. First, we don't care about the range [0..(n-1)], we just care about repeating an action n times. A more direct way to do this is the following:
replicateM n (get >>= \(a, b) -> put (b, a + b))
The result is a list of unit which is unused, so a more efficient version is:
replicateM_ n (get >>= \(a, b) -> put (b, a + b))
There is already a function for the common pattern of get followed by put named modify, which is defined as \f -> get >>= put . f. Therefore:
replicateM_ n (modify (\(a, b) -> (b, a + b)))
Then there is the part:
>>= (\_ -> get >>= (\(a, b) -> return a)))
Any time we don't care about the previous result we can use >>.
>> get >>= (\(a, b) -> return a))
This is:
>> get >>= return . fst
m >>= return . f simplifies to fmap f m:
>> fmap fst get
Now we have, in total:
fib n =
evalState
( replicateM_ n (modify (\(a, b) -> (b, a + b)))
>> fmap fst get
)
(0, 1)
We might also use, for comparison:
fib n =
fst
( evalState
( replicateM_ n (modify (\(a, b) -> (b, a + b)))
>> get
)
(0, 1)
)
And then because I am silly:
fib =
fst
. flip evalState (0, 1)
. (>> get)
. flip replicateM_ (modify (snd &&& uncurry (+)))
Why would you want to use the state monad over here?
You wouldn't. This is clear because we only use the state value; the other value is always unit and discarded. In other words, we only need n (i.e. which Fibonacci number to find) at the beginning and afterwards we only need the accumulated tuple.
Sometimes you think to have a string of compositions like h . g . f but you want to send two arguments through instead of just one. That is when State may be applicable.
If some functions read and some write the state (the second argument), or do both, then State fits the bill. If there are only readers then use Reader and if there are only writers then use Writer.
We can alter the example to make better use of the State Monad. I will make the tuple disappear!
fib =
flip evalState 0
. foldr (=<<) (return 1)
. flip replicate (\x -> get >>= \y -> put x $> x + y)
So the docs state: get :: m s -- Return the state from the internals of the monad (see here).
But I remember very well that when I tried to wrap my head around the State Monad this didn't help me a lot.
I can only recommend playing around with :i and :t in ghci and test out different sub-expressions. Just to get a feel for it. A bit like this:
import Control.Monad.State.Lazy
runState (get) 0
runState (get >>= \x -> put (x+1)) 0
:t return 1 :: State Int Int
runState (return 1) 0
runState (return 1 >>= \x -> (get >>= \y -> return (x+y))) 0
-- Keeping a pair of (predecessor/current) in the state:
let f = (get >>= (\(a,b) -> put (b,a+b))) :: State (Int, Int) ()
runState (f >> f >> f >> f >> f >> f) (0,1)
-- only keeping the predecessor in the state:
let f x = (get >>= (\y -> put x >> return (x+y))) :: State Int Int
runState (return 1 >>= f >>= f >>= f >>= f >>= f >>= f) 0
Also play around with modify, runState, evalState, execState.

Why does this haskell code not terminate

import Control.Monad.State.Lazy
type Queue a = [a]
push :: a -> State (Queue a) ()
push x = state (\xs -> ((),xs++[x]))
pop :: State (Queue a) a
pop = state (\(x:xs) -> (x,xs))
queueManip :: State (Queue Int) Int
queueManip =
do
mapM_ push [1..]
a <- pop
return a
main :: IO()
main = do
let (a,_) = runState queueManip []
print a
Shouldn't the mapM_ be lazy ? Besides for implementing a queue shouldn't the complexity be O(1)?
Because the append (++) itself is lazy ...
What if I'm evil and use
push' :: Int -> State (Queue Int) ()
push' 1052602983 = state $ \_ -> ((), []) -- "Muarhar!"
push' x = state $ \xs -> ((),xs++[x])
Then mapM push' [1..] should clearly render the state as [1052602983, 1052602984 ..]. It would be wrong for pop to yield 1. But mapM can't possibly know this, without first evaluating a billion other numbers. Actually pushing them to the state is irrelevant here, and it also doesn't matter that push could be completely lazy: mapM at least has to give it a chance to check any given number, before handing on the monadic program flow.
Note that do mapM_ push [1..3]; something is the same as:
do push 1; push 2; push 3; something
so that should explain why
do mapM_ push [1..]; something
never gets around to executing something.
If you look at the definition of the State monad:
type State s a = s -> (a, s)
instance Monad (State s) where
return a = \s -> (a,s)
m >>= g = wpAB
where
wpAB = \s1 -> let (v2, s2) = m s1
(v3, s3) = g v2 s2
in (v3, s3)
-- (newtypes and such have been removed to declutter the code)
you see that the value of m >>= g always depends on g. Contrast that with the definition of Maybe monad:
instance Monad Maybe where
return x = Just x
(>>=) m g = case m of
Nothing -> Nothing
Just x -> g x
where m >>= g can be independent of g which explains how the Maybe monad can short-circuit a do-chain.

How to define foldM using foldr/foldl (if it is possible)?

I wanted to make a generic function that folds over a wide range of inputs (see Making a single function work on lists, ByteStrings and Texts (and perhaps other similar representations)). As one answer suggested, the ListLike is just for that. Its FoldableLL class defines an abstraction for anything that is foldable. However, I need a monadic fold. So I need to define foldM in terms of foldl/foldr.
So far, my attempts failed. I tried to define
foldM'' :: (Monad m, LL.FoldableLL full a) => (b -> a -> m b) -> b -> full -> m b
foldM'' f z = LL.foldl (\acc x -> acc >>= (`f` x)) (return z)
but it runs out of memory on large inputs - it builds a large unevaluated tree of computations. For example, if I pass a large text file to
main :: IO ()
main = getContents >>= foldM'' idx 0 >> return ()
where
-- print the current index if 'a' is found
idx !i 'a' = print i >> return (i + 1)
idx !i _ = return (i + 1)
it eats up all memory and fails.
I have a feeling that the problem is that the monadic computations are composed in a wrong order - like ((... >>= ...) >>= ...) instead of (... >>= (... >>= ...)) but so far I didn't find out how to fix it.
Workaround: Since ListLike exposes mapM_, I constructed foldM on ListLikes by wrapping the accumulator into the state monad:
modifyT :: (Monad m) => (s -> m s) -> StateT s m ()
modifyT f = get >>= \x -> lift (f x) >>= put
foldLLM :: (LL.ListLike full a, Monad m) => (b -> a -> m b) -> b -> full -> m b
foldLLM f z c = execStateT (LL.mapM_ (\x -> modifyT (\b -> f b x)) c) z
While this works fine on large data sets, it's not very nice. And it doesn't answer the original question, if it's possible to define it on data that are just FoldableLL (without mapM_).
So the goal is to reimplement foldM using either foldr or foldl. Which one should it be? We want the input to be processed lazily and allow for infinte lists, this rules out foldl. So foldr is it going to be.
So here is the definition of foldM from the standard library.
foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldM _ a [] = return a
foldM f a (x:xs) = f a x >>= \fax -> foldM f fax xs
The thing to remember about foldr is that its arguments simply replace [] and : in the list (ListLike abstracts over that, but it still serves as a guiding principle).
So what should [] be replaced with? Clearly with return a. But where does a come from? It won’t be the initial a that is passed to foldM – if the list is not empty, when foldr reaches the end of the list, the accumulator should have changed. So we replace [] by a function that takes an accumulator and returns it in the underlying monad: \a -> return a (or simply return). This also gives the type of the thing that foldr will calculate: a -> m a.
And what should we replace : with? It needs to be a function b -> (a -> m a) -> (a -> m a), taking the first element of the list, the processed tail (lazily, of course) and the current accumulator. We can figure it out by taking hints from the code above: It is going to be \x rest a -> f a x >>= rest. So our implementation of foldM will be (adjusting the type variables to match them in the code above):
foldM'' :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldM'' f z list = foldr (\x rest a -> f a x >>= rest) return list z
And indeed, now your program can consume arbitrary large input, spitting out the results as you go.
We can even prove, inductively, that the definitions are semantically equal (although we should probably do coinduction or take-induction to cater for infinite lists).
We want to show
foldM f a xs = foldM'' f a xs
for all xs :: [b]. For xs = [] we have
foldM f a []
≡ return a -- definition of foldM
≡ foldr (\x rest a -> f a x >>= rest) return [] a -- definition of foldr
≡ foldM'' f a [] -- definition of foldM''
and, assuming we have it for xs, we show it for x:xs:
foldM f a (x:xs)
≡ f a x >>= \fax -> foldM f fax xs --definition of foldM
≡ f a x >>= \fax -> foldM'' f fax xs -- induction hypothesis
≡ f a x >>= \fax -> foldr (\x rest a -> f a x >>= rest) return xs fax -- definition of foldM''
≡ f a x >>= foldr (\x rest a -> f a x >>= rest) return xs -- eta expansion
≡ foldr (\x rest a -> f a x >>= rest) return (x:xs) -- definition of foldr
≡ foldM'' f a (x:xs) -- definition of foldM''
Of course this equational reasoning does not tell you anything about the performance properties you were interested in.

Is Haskell's mapM not lazy?

UPDATE: Okay this question becomes potentially very straightforward.
q <- mapM return [1..]
Why does this never return?
Does mapM not lazily deal with infinite lists?
The code below hangs. However, if I replace line A by line B, it doesn't hang anymore. Alternatively, if I preceed line A by a "splitRandom $", it also doesn't hang.
Q1 is: Is mapM not lazy? Otherwise, why does replacing line A with line B "fix this" code?
Q2 is: Why does preceeding line A with splitRandom "solve" the problem?
import Control.Monad.Random
import Control.Applicative
f :: (RandomGen g) => Rand g (Double, [Double])
f = do
b <- splitRandom $ sequence $ repeat $ getRandom
c <- mapM return b -- A
-- let c = map id b -- B
a <- getRandom
return (a, c)
splitRandom :: (RandomGen g) => Rand g a -> Rand g a
splitRandom code = evalRand code <$> getSplit
t0 = do
(a, b) <- evalRand f <$> newStdGen
print a
print (take 3 b)
The code generates an infinite list of random numbers lazily. Then it generates a single random number. By using splitRandom, I can evaluate this latter random number first before the infinite list. This can be demonstrated if I return b instead of c in the function.
However, if I apply the mapM to the list, the program now hangs. To prevent this hanging, I have to apply splitRandom again before the mapM. I was under the impression that mapM can lazily
Well, there's lazy, and then there's lazy. mapM is indeed lazy in that it doesn't do more work than it has to. However, look at the type signature:
mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]
Think about what this means: You give it a function a -> m b and a bunch of as. A regular map can turn those into a bunch of m bs, but not an m [b]. The only way to combine the bs into a single [b] without the monad getting in the way is to use >>= to sequence the m bs together to construct the list.
In fact, mapM is precisely equivalent to sequence . map.
In general, for any monadic expression, if the value is used at all, the entire chain of >>=s leading to the expression must be forced, so applying sequence to an infinite list can't ever finish.
If you want to work with an unbounded monadic sequence, you'll either need explicit flow control--e.g., a loop termination condition baked into the chain of binds somehow, which simple recursive functions like mapM and sequence don't provide--or a step-by-step sequence, something like this:
data Stream m a = Nil | Stream a (m (Stream m a))
...so that you only force as many monad layers as necessary.
Edit:: Regarding splitRandom, what's going on there is that you're passing it a Rand computation, evaluating that with the seed splitRandom gets, then returning the result. Without the splitRandom, the seed used by the single getRandom has to come from the final result of sequencing the infinite list, hence it hangs. With the extra splitRandom, the seed used only needs to thread though the two splitRandom calls, so it works. The final list of random numbers works because you've left the Rand monad at that point and nothing depends on its final state.
Okay this question becomes potentially very straightforward.
q <- mapM return [1..]
Why does this never return?
It's not necessarily true. It depends on the monad you're in.
For example, with the identity monad, you can use the result lazily and it terminates fine:
newtype Identity a = Identity a
instance Monad Identity where
Identity x >>= k = k x
return = Identity
-- "foo" is the infinite list of all the positive integers
foo :: [Integer]
Identity foo = do
q <- mapM return [1..]
return q
main :: IO ()
main = print $ take 20 foo -- [1 .. 20]
Here's an attempt at a proof that mapM return [1..] doesn't terminate. Let's assume for the moment that we're in the Identity monad (the argument will apply to any other monad just as well):
mapM return [1..] -- initial expression
sequence (map return [1 ..]) -- unfold mapM
let k m m' = m >>= \x ->
m' >>= \xs ->
return (x : xs)
in foldr k (return []) (map return [1..]) -- unfold sequence
So far so good...
-- unfold foldr
let k m m' = m >>= \x ->
m' >>= \xs ->
return (x : xs)
go [] = return []
go (y:ys) = k y (go ys)
in go (map return [1..])
-- unfold map so we have enough of a list to pattern-match go:
go (return 1 : map return [2..])
-- unfold go:
k (return 1) (go (map return [2..])
-- unfold k:
(return 1) >>= \x -> go (map return [2..]) >>= \xs -> return (x:xs)
Recall that return a = Identity a in the Identity monad, and (Identity a) >>= f = f a in the Identity monad. Continuing:
-- unfold >>= :
(\x -> go (map return [2..]) >>= \xs -> return (x:xs)) 1
-- apply 1 to \x -> ... :
go (map return [2..]) >>= \xs -> return (1:xs)
-- unfold >>= :
(\xs -> return (1:xs)) (go (map return [2..]))
Note that at this point we'd love to apply to \xs, but we can't yet! We have to instead continue unfolding until we have a value to apply:
-- unfold map for go:
(\xs -> return (1:xs)) (go (return 2 : map return [3..]))
-- unfold go:
(\xs -> return (1:xs)) (k (return 2) (go (map return [3..])))
-- unfold k:
(\xs -> return (1:xs)) ((return 2) >>= \x2 ->
(go (map return [3..])) >>= \xs2 ->
return (x2:xs2))
-- unfold >>= :
(\xs -> return (1:xs)) ((\x2 -> (go (map return [3...])) >>= \xs2 ->
return (x2:xs2)) 2)
At this point, we still can't apply to \xs, but we can apply to \x2. Continuing:
-- apply 2 to \x2 :
(\xs -> return (1:xs)) ((go (map return [3...])) >>= \xs2 ->
return (2:xs2))
-- unfold >>= :
(\xs -> return (1:xs)) (\xs2 -> return (2:xs2)) (go (map return [3..]))
Now we've gotten to a point where neither \xs nor \xs2 can be reduced yet! Our only choice is:
-- unfold map for go, and so on...
(\xs -> return (1:xs))
(\xs2 -> return (2:xs2))
(go ((return 3) : (map return [4..])))
So you can see that, because of foldr, we're building up a series of functions to apply, starting from the end of the list and working our way back up. Because at each step the input list is infinite, this unfolding will never terminate and we will never get an answer.
This makes sense if you look at this example (borrowed from another StackOverflow thread, I can't find which one at the moment). In the following list of monads:
mebs = [Just 3, Just 4, Nothing]
we would expect sequence to catch the Nothing and return a failure for the whole thing:
sequence mebs = Nothing
However, for this list:
mebs2 = [Just 3, Just 4]
we would expect sequence to give us:
sequence mebs = Just [3, 4]
In other words, sequence has to see the whole list of monadic computations, string them together, and run them all in order to come up with the right answer. There's no way sequence can give an answer without seeing the whole list.
Note: The previous version of this answer asserted that foldr computes starting from the back of the list, and wouldn't work at all on infinite lists, but that's incorrect! If the operator you pass to foldr is lazy on its second argument and produces output with a lazy data constructor like a list, foldr will happily work with an infinite list. See foldr (\x xs -> (replicate x x) ++ xs) [] [1...] for an example. But that's not the case with our operator k.
This question is showing very well the difference between the IO Monad and other Monads. In the background the mapM builds an expression with a bind operation (>>=) between all the list elements to turn the list of monadic expressions into a monadic expression of a list. Now, what is different in the IO monad is that the execution model of Haskell is executing expressions during the bind in the IO Monad. This is exactly what finally forces (in a purely lazy world) something to be executed at all.
So IO Monad is special in a way, it is using the sequence paradigm of bind to actually enforce execution of each step and this is what our program makes to execute anything at all in the end. Others Monads are different. They have other meanings of the bind operator, depending on the Monad. IO is actually the one Monad which execute things in the bind and this is the reason why IO types are "actions".
The following example show that other Monads do not enforce execution, the Maybe monad for example. Finally this leds to the result that a mapM in the IO Monad returns an expression, which - when executed - executes each single element before returning the final value.
There are nice papers about this, start here or search for denotational semantics and Monads:
Tackling the awkward squad: http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/mark.pdf
Example with Maybe Monad:
module Main where
fstMaybe :: [Int] -> Maybe [Int]
fstMaybe = mapM (\x -> if x == 3 then Nothing else Just x)
main = do
let r = fstMaybe [1..]
return r
Let's talk about this in a more generic context.
As the other answers said, the mapM is just a combination of sequence and map. So the problem is why sequence is strict in certain Monads. However, this is not restricted to Monads but also Applicatives since we have sequenceA which share the same implementation of sequence in most cases.
Now look at the (specialized for lists) type signature of sequenceA :
sequenceA :: Applicative f => [f a] -> f [a]
How would you do this? You were given a list, so you would like to use foldr on this list.
sequenceA = foldr f b where ...
--f :: f a -> f [a] -> f [a]
--b :: f [a]
Since f is an Applicative, you know what b coule be - pure []. But what is f?
Obviously it is a lifted version of (:):
(:) :: a -> [a] -> [a]
So now we know how sequenceA works:
sequenceA = foldr f b where
f a b = (:) <$> a <*> b
b = pure []
or
sequenceA = foldr ((<*>) . fmap (:)) (pure [])
Assume you were given a lazy list (x:_|_). The above definition of sequenceA gives
sequenceA (x:_|_) === (:) <$> x <*> foldr ((<*>) . fmap (:)) (pure []) _|_
=== (:) <$> x <*> _|_
So now we see the problem was reduced to consider weather f <*> _|_ is _|_ or not. Obviously if f is strict this is _|_, but if f is not strict, to allow a stop of evaluation we require <*> itself to be non-strict.
So the criteria for an applicative functor to have a sequenceA that stops on will be
the <*> operator to be non-strict. A simple test would be
const a <$> _|_ === _|_ ====> strict sequenceA
-- remember f <$> a === pure f <*> a
If we are talking about Moands, the criteria is
_|_ >> const a === _|_ ===> strict sequence

Resources