Why the Haskell sequence function can't be lazy or why recursive monadic functions can't be lazy

前端 未结 3 1852
青春惊慌失措
青春惊慌失措 2020-12-18 22:23

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 t

3条回答
  •  醉梦人生
    2020-12-18 23:01

    You're not quite grokking the mechanics of bind:

    (>>=) :: Monad m => m a -> (a -> m b) -> m b
    

    Here's an implementation of sequence that only works on 3-length lists:

    sequence3 (ma:mb:mc:[]) = ma >>= (\a-> mb >>= (\b-> mc >>= (\c-> return [a,b,c] )))
    

    You see how we have to "run" each "monadic action" in the list before we can return the outer constructor (i.e. the outermost cons, or (:))? Try implementing it differently if you don't believe.

    This is one reason monads are useful for IO: there is an implicit sequencing of effects when you bind two actions.

    You also have to be careful about using the terms "lazy" and "strict". It's true with sequence that you must traverse the whole list before the final result can be wrapped, but the following works perfectly well:

    Prelude Control.Monad> sequence3 [Just undefined, Just undefined, Nothing]
    Nothing
    

提交回复
热议问题