The reason is that even though the value of the head element of sequence someList
depends only on the first elemenent of someList
, the effect of sequence someList
can generally depend on all the effects of someList
(and it does for most monads). Therefore, if we want to evaluate the head element, we still need to evaluate all the effects.
For example, if we have a list of Maybe
values, the result of sequence someList
is Just
only if all the elements of someList
are Just
. So if we try to sequence
an infinite list, we'd need to examine its infinite number of elements if they're all Just
.
The same applies for Cont
.
In the continuation monad, we can escape any time from the computation and return a result that is different from what has been computed so far.
Consider the following example:
test :: (Num a, Enum a) => a
test = flip runCont head $
callCC $ \esc -> do
sequence (map return [0..100] ++ [esc [-1]])
or directly using cont
instead of callCC
:
test' :: (Num a, Enum a) => a
test' = flip runCont head $
sequence (map return [0..100] ++ [cont (const (-1))])
The result of test
is just -1
. After processing the first 100 elements, the final element can decide to escape all of this and return -1
instead. So in order to see what is the head
element of sequence someList
in Cont
, we again need to compute them all.