相关疑难解决方法(0)

为什么Haskell序列函数不能是懒惰的,或者为什么递归monadic函数不能是懒惰的

使用问题列出按广度优先顺序列出目录的所有内容效率低下我了解到效率低是由于递归monad函数的奇怪行为.

尝试

sequence $ map return [1..]::[[Int]]
sequence $ map return [1..]::Maybe [Int]
Run Code Online (Sandbox Code Playgroud)

和ghci将陷入无休止的计算.

如果我们以更易读的形式重写序列函数,如下所示:

sequence' []     = return []
sequence' (m:ms) = do {x<-m; xs<-sequence' ms; return (x:xs)}
Run Code Online (Sandbox Code Playgroud)

并尝试:

sequence' $ map return [1..]::[[Int]]
sequence' $ map return [1..]::Maybe [Int]
Run Code Online (Sandbox Code Playgroud)

我们得到了相同的情况,无休止的循环.

尝试一个有限的列表

sequence' $ map return [1..]::Maybe [Int]
Run Code Online (Sandbox Code Playgroud)

Just [1,2,3,4..]经过很长时间的等待,它会弹出预期的结果.

根据我们的尝试,我们可以得出结论,尽管序列的定义"似乎是懒惰的,但它是严格的,并且必须在序列结果之前得出所有数字"才能打印出来.

如果我们定义一个函数,不仅仅是序列'

iterateM:: Monad m => (a -> m a) -> a -> m [a]
iterateM f x = (f x) >>= iterateM0 f …
Run Code Online (Sandbox Code Playgroud)

monads recursion haskell loops lazy-evaluation

12
推荐指数
3
解决办法
3750
查看次数

标签 统计

haskell ×1

lazy-evaluation ×1

loops ×1

monads ×1

recursion ×1