Pro*_*het 5 haskell tuples list destructuring lazy-evaluation
当尝试使用 foldr 实现 dropWhile 时,我想出的第一个算法是
dropWhile' :: (a -> Bool) -> [a] -> [a]
dropWhile' pred = fst . foldr (\cur (acc, xs) ->
if pred cur
then (acc, cur:xs)
else (cur:xs, cur:xs)) ([], [])
Run Code Online (Sandbox Code Playgroud)
虽然这有效,但它会导致无限列表上的堆栈溢出而没有给出任何值。因为我不确定,为什么这不起作用,我只是玩弄这个函数,直到我想出这个:
dropWhile' :: (a -> Bool) -> [a] -> [a]
dropWhile' pred = fst . foldr (\cur t -> let (acc, xs) = t in
if pred cur
then (acc, cur:xs)
else (cur:xs, cur:xs)) ([], [])
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这个和第一个之间的唯一区别是,这里我在(acc, xs)let 绑定中解构元组,而不是直接在函数参数内部解构。出于某种奇怪的原因,此代码适用于无限列表。如果有人知道为什么会这样,请告诉我。
Haskell 中的 Let 表达式是惰性的:
Let 表达式
(...) 模式绑定是惰性匹配的;隐含的 ~ 使这些模式无可辩驳。
相比之下, lambda 抽象 desugar 到case,从而使构造函数模式严格:
Curried 应用程序和 lambda 抽象
翻译:以下身份成立:
\ p1 … pn -> e = \ x1 … xn -> case (x1, …, xn) of (p1, …, pn) -> e