Re: [问题] Lazy Evaluation?

楼主: Favonia (00010110110001101010100)   2011-11-15 01:14:36
※ 引述《slyfox (klanloss)》之铭言:
: 失败版:
: sequenceWhile :: Monad m => (a -> Bool) -> [m a] -> m [a]
: sequenceWhile f ms = sequence ms >>= return . takeWhile f
: getCharUntil' c = sequenceWhile (/=c) $ repeat getChar
: 失败版会一直读不停
: Lazy evaluation 很耐死的,一定是有什么误会…
: → slyfox:但在此例 sequence 被 >>= 规定要"算到底"吧? 11/14 15:10
(不好意思违反版规建议,请帮我把推文删掉 orz)
>>= 需要判断左边有没有会导致错误的指令,而 sequence ms
要如何决定有没有会导致错误的指令?只能全部看过一次!可惜这
个串行怎么看都看不完。
题外话是 sequence 为了检查会不会产生错误时不需要把每个
指令的结果都“展开到最后”,也就是“算到底”。实际上除非用
deepseq 之类的东西恶搞否则很难算到底...
=== 真相版 ===
上面的理解有个作弊的地方,就是我假设 sequenceWhile 要
算到至少 Weak head normal form (WHNF). 实际上得从 main 开
始逆推才知道什么是非算不可的...
Haskell 各个函数计算上的意义比较像是“如何拖人下水”
(下水 = 变身成 WHNF)或“如何变身”。理论上有人要拖
sequence ms 下水时,它可以先用 pattern matching 拖人下水,
然后再根据定义变身成 foldr. 可惜这样还不够(还不是 WHNF
所以还没掉到水里),所以变身成 foldr 后继续被拖。接着
foldr 可以再用 pattern matching 拖他的参数下水... 文章中
拖来拖去的关系恰好会尝试把串行中每个元素都拖下去,所以跑
不完。
凡是总要有起头,基本上一开始 main 就会直接被拖下水,
看看多少人会一起掉下去。喔,然后编译器会在尽量保留语意的
情况下(理想上是完全保留语意,但是...)用比较有效率方法
实作这种拖人下水的机制;尤其 GHC 实作一堆奇怪的最佳化,
最后真正跑的程式码可能跟你在 Prelude.hs 翻到的相去甚远...
作者: godfat (godfat 真常)   2010-01-15 11:01:00
谢谢 :) 是否修改推文则由原作者决定吧
作者: slyfox (klanloss)   2010-01-15 12:06:00
了解 感谢~ 鱼好吃 钓竿有好推荐吗?

Links booklink

Contact Us: admin [ a t ] ucptt.com