【问题标题】:Haskell Tuple destructuring on infinite lists behaves differently when destructuring the Tuple as an argument than when destructuring using letHaskell Tuple 在无限列表上解构在将 Tuple 作为参数解构时与使用 let 解构时的行为不同
【发布时间】:2020-10-02 18:47:33
【问题描述】:

当尝试使用 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)) ([], [])

虽然这可行,但它会导致无限列表上的堆栈溢出而不给出任何值。 因为我不确定,为什么这不起作用,所以我只是玩弄了这个函数,直到我想出了这个:

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)) ([], [])

如您所见,这个和第一个之间的唯一区别是,这里我在 let 绑定中解构元组 (acc, xs),而不是直接在函数参数中解构。由于某些奇怪的原因,此代码适用于无限列表。 如果有人知道为什么会这样,请告诉我。

【问题讨论】:

    标签: list haskell tuples lazy-evaluation destructuring


    【解决方案1】:

    让 Haskell 中的表达式是惰性的:

    Let Expressions

    (...) 模式绑定是惰性匹配的;隐含的 ~ 使这些模式无可辩驳。

    相比之下,lambda 抽象去糖为case,从而使构造函数模式变得严格:

    Curried applications and lambda abstractions

    翻译:以下身份成立:

    \ p1 … pn -> e = \ x1 … xn -> case (x1, …, xn) of (p1, …, pn) -> e

    【讨论】:

    • ...您可以使用提示~ 使 lambda 的模式显式地变得懒惰并获得两全其美(let 在无限列表和 lambda 上的良好行为)美学)。 \cur ~(acc, xs) -> if ...
    【解决方案2】:

    粗略地说,

    \cur (acc, xs) -> use cur acc xs
    

    在评估 use ... 之前立即强制评估第二个参数。 在foldr 中,这会在执行任何其他操作之前处理列表的尾部。如果列表是无限的,我们将陷入无限递归。

    同样适用

    \cur t -> case t of (acc, xs) -> use cur acc xs
    

    相反,

    \cur t -> use cur (fst t) (snd t)
    

    不会立即强制评估第二个参数t,因为 Haskell 是惰性的。只有当use 确实需要它的第二个或第三个参数时,t 的评估才会触发。

    等价地,我们可以写

    \cur t -> case t of ~(acc, xs) -> use cur acc xs
    -- or
    \cur ~(acc, xs) -> use cur acc xs
    

    达到同样的效果,使用惰性/无可辩驳的模式来延迟第二个参数的解构。当使用letwhere时,(顶层)模式是隐式惰性的,所以我们也可以写

    \cur t -> let (acc, xs) = t in use cur acc xs
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 2012-07-25
      • 2015-07-06
      • 2012-07-14
      • 1970-01-01
      相关资源
      最近更新 更多