[問題] Lazy Evaluation?

作者: slyfox (klanloss)   2011-11-12 13:30:37
剛剛在練習寫 Haskell 時,遇到個小問題,一時不解上來發問。
我想寫一個 function 用來讀 stdin 直到讀到特定的字元
成功版:
getCharUntil :: Char -> IO [Char]
getCharUntil c = do x <- getChar
if x == c then return []
else do xs <- getCharUntil c
return $ x : xs
失敗版:
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 很耐死的,一定是有什麼誤會…
感謝
作者: godfat (godfat 真常)   2010-01-13 05:53:00
因為 sequence 吧?
作者: ccshan (善終結)   2010-01-13 14:10:00
失敗版的意思是:先讀無窮多個字元,再取其開頭部份。
作者: slyfox (klanloss)   2010-01-13 14:34:00
啊! 所以 >>= 是兇手!!想起來 sequence 是用 foldr 實做的了 難怪!
作者: Favonia (00010110110001101010100)   2010-01-13 20:29:00
>>= 應該不會強迫左邊算到底,所以應該是無辜的 xD
作者: slyfox (klanloss)   2010-01-14 06:13:00
那我還是不理解。。。
作者: Favonia (00010110110001101010100)   2010-01-14 06:19:00
我的意思是說只有 >>= 並不妨礙,可能你的理解是正確的 xD
作者: slyfox (klanloss)   2010-01-14 15:10:00
但在此例 sequence 被 >>= 規定要"算到底"吧?
作者: Favonia (00010110110001101010100)   2010-01-14 21:13:00
>>= 只需要判斷左邊沒有 fail 即可,但 sequence 要如何決定有沒有 fail? 只能全部看過一次!只要有個 fail 就會全部 fail. 然後 sequence 為了應付 >>= 也只需要檢查有沒有fail 就好,不需要「算到底」。除非用 deepseq 之類的東西惡搞否則很難算到底...上面的理解有個作弊的地方,就是我假設 sequenceWhile 要算到至少 Weak head normal form. 實際上得從 main 開始逆推才知道什麼是非算不可的...
作者: godfat (godfat 真常)   2010-01-14 23:24:00
請不要推文超過三行...

Links booklink

Contact Us: admin [ a t ] ucptt.com