【问题标题】:using foldr in elm/haskell在 elm/haskell 中使用 foldr
【发布时间】:2020-12-02 00:02:32
【问题描述】:

我在使用 foldr 解决这个问题时遇到了麻烦。我理解 foldr 可以解决简单的问题(例如 foldr (+) 5 [1,2,3,4]),但这更复杂:

问题:q2 的值是多少?

findSubsequence next highest = case next == highest + 1 of
  True -> next
  False -> highest

q2 = (foldr findSubsequence 0 [5,6,8,4,7,3,2,1,0,2,3,1,0]
     ,foldr findSubsequence 0 [0,1,3,2,0,1,2,3,7,4,8,6,5]
     ,foldr findSubsequence 0 [1,2,3,4,3,2,1]
     ,foldr findSubsequence 0 [4,3,2,1,2,3,4]
     )

对每个列表使用 foldr 会为您提供价值并将结果列表放在一起,结果列表为 [5,3,4,4] 但我不知道解决此问题的过程。帮助将不胜感激:)

【问题讨论】:

  • 我先扩展foldr的定义。

标签: haskell fold elm


【解决方案1】:

foldr 中的r 表示它是一个右关联折叠。

如果您不熟悉该术语,关联性是运算符的一个属性,它告诉我们如何解释由不带括号的运算符的顺序应用组成的模棱两可的表达式。通过指定运算符的关联性,我们通过指定表达式应从其计算的结尾来解决歧义(因此使用 rightleft)。

举个例子,我们应该如何解释下面的表达式?

1 / 2 / 3 / 4

答案取决于运算符/ 的关联性。如果运算符是左结合的,答案是:

((1 / 2) / 3) / 4

另一方面,右关联 / 将评估为:

1 / (2 / (3 / 4)))

本质上,折叠是一种通过在序列元素之间散布运算符来形成此类表达式的方法。但是,由于关联性,显然有两种同样有意义的方法可以做到这一点,即foldrfoldl

将此应用于元组的最后一个元素(为简洁起见,将 findSubsequence 重命名为 f)会导致:

foldr f 0 [4,3,2,1,2,3,4] = f 4 (f 3 (f 2 (f 1 (f 2 (f 3 (f 4 0))))))
                          = f 4 (f 3 (f 2 (f 1 (f 2 (f 3 0)))))
                          = f 4 (f 3 (f 2 (f 1 (f 2 0))))
                          = f 4 (f 3 (f 2 (f 1 0)))
                          = f 4 (f 3 (f 2 1))
                          = f 4 (f 3 2)
                          = f 4 3
                          = 4

【讨论】:

    【解决方案2】:

    免责声明:这是在 Haskell 中,我不知道 a `f` b 语法在 Elm 中是否有效,但它不会改变您只需编写 f a b 而不是 @ 的结果987654323@你在哪里可以找到它


    q2 的一个组件(我将取最后一个 - 因为它是其中最短的):

    foldr findSubsequences 0 [4,3,2,1,2,3,4]
    { with fSs = findSubsequences - note that [] is replaced with the 0 of the first arg }
    = 4 `fSs` (3 `fSs` (2 `fSs` (1 `fSs`(2 `fSs` (3 `fSs` (4 `fSs` 0))))))
    { 4 is not 0+1 so 4 `fSs` 0 = 0 }
    = 4 `fSs` (3 `fSs` (2 `fSs` (1 `fSs`(2 `fSs` (3 `fSs` 0)))))
    { 3 is not 0+1  so 3 `fSs` 0 = 0 }
    = 4 `fSs` (3 `fSs` (2 `fSs` (1 `fSs`(2 `fSs` 0))))
    { 2 is not 0+1  so 2 `fSs` 0 = 0 }
    = 4 `fSs` (3 `fSs` (2 `fSs` (1 `fSs`0)))
    { 1 IS 0+1  so 1 `fSs` 0 = 1 }
    = 4 `fSs` (3 `fSs` (2 `fSs` 1))
    { 2 IS 1+1 so 2 `fSs` 1 = 2 }
    = 4 `fSs` (3 `fSs` 2)
    { 3 IS 2+1 so 3 `fSs` 2 = 3 }
    = 4 `fSs` 3
    { 4 IS 3+1 so 4 `fSs` 3 = 4 }
    = 4
    

    每一步都只是使用你的定义

    我希望你也能对其他情况做同样的事情:D


    请注意,我使用了简单的替换技巧

    • :findSubsequences
    • []0`findSubsequences` 的第一个参数)

    您将输入列表表示为a:b:c:...:[]

    【讨论】:

    • a `f` b 是 Elm 中的有效语法,它使用 :: 作为列表缺点,而不是 Haskell 的 :
    猜你喜欢
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 2018-11-12
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多