With the question Listing all the contents of a directory by breadth-first order results in low efficiencyI learned that the low efficiency is due to a strange behavior of the recursive monad functions.
Try
sequence $ map return [1..]::[[Int]]
sequence $ map return [1..]::Maybe [Int]
and ghci will fall into an endless calculation.
If we rewrite the sequence function in a more readable form like follows:
sequence' [] = return []
sequence' (m:ms) = do {x<-m; xs<-sequence' ms; return (x:xs)}
and try:
sequence' $ map return [1..]::[[Int]]
sequence' $ map return [1..]::Maybe [Int]
we get the same situation, an endless loop.
Try a finite list
sequence' $ map return [1..]::Maybe [Int]
it will spring out the expected result Just [1,2,3,4..]
after a long time waiting.
From what we tried,we can come to the conclusion that although the definition of sequence' seems to be lazy, it is strict and has to make out all the numbers before the result of sequence' can be printed.
Not only just sequence', if we define a function
iterateM:: Monad m => (a -> m a) -> a -> m [a]
iterateM f x = (f x) >>= iterateM0 f >>= return.(x:)
and try
iterateM (>>=(+1)) 0
then endless calculation occurs.
As we all know,the non-monadic iterate is defined just like the above iterateM, but why the iterate is lazy and iterateM is strict. As we can see from above, both iterateM and sequence' are recursive monadic functions.Is there some thing strange with recursive monadic functions