简体   繁体   English

在 elm/haskell 中使用 foldr

[英]using foldr in elm/haskell

I'm having trouble solving this problem using foldr.我在使用 foldr 解决这个问题时遇到了麻烦。 I understand foldr for simple problems (like foldr (+) 5 [1,2,3,4]) but this is more complicated:我理解 foldr 的简单问题(如 foldr (+) 5 [1,2,3,4]),但这更复杂:

Question: What is the value of q2?问题: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]
     )

Using foldr for each list gives you the value and put together the resulting list is [5,3,4,4] but I don't know the process of solving this.对每个列表使用 foldr 为您提供值并将结果列表放在一起是 [5,3,4,4] 但我不知道解决这个问题的过程。 Help would be appreciated :)帮助将不胜感激:)

The r in foldr signifies that it is a right-associative fold. foldrr表示它是右结合折叠。

In case you're not familiar with the term, associativity is a property of operators that tells us how to interpret ambiguous expressions composed of sequential applications of the operator without parentheses.如果您不熟悉这个术语,结合性是运算符的一个属性,它告诉我们如何解释由不带括号的运算符的顺序应用组成的歧义表达式。 By specifying the associativity of an operator, we resolve the ambiguity by specifying the end from which the expression should be evaluated (hence the use of right and left ).通过指定运算符的结合性,我们通过指定应评估表达式的结尾(因此使用rightleft )来解决歧义。

As an example, how should we interpret the following expression?例如,我们应该如何解释以下表达式?

1 / 2 / 3 / 4

The answer depends on the associativity of the operator / .答案取决于运算符/ If the operator is left-associative, the answer is:如果运算符是左结合的,答案是:

((1 / 2) / 3) / 4

On the other hand, a right-associative / would evaluate to:另一方面,右结合/将评估为:

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

Folds are, in essence, a way of forming such expressions by interspersing an operator between the elements of a sequence.折叠本质上是一种通过在序列的元素之间散布运算符来形成此类表达式的方式。 However, because of associativity, there are clearly two equally meaningful ways of doing this, resulting in foldr and foldl .但是,由于关联性,显然有两种同样有意义的方法来执行此操作,即foldrfoldl

Applying this to the last element of your tuple (renaming findSubsequence to f for brevity) results in:将此应用于元组的最后一个元素(为简洁起见,将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

disclaimer: this is in Haskell and I don't know if the a `f` b syntax is valid in Elm but it will not change the outcome you just had to write fab instead of a `f` b where ever you find it免责声明:这是在 Haskell 中,我不知道a `f` b语法在 Elm 中是否有效,但它不会改变你只需要在任何地方编写fab而不是a `f` b结果


take one component of q2 (I'll take the last - because it's the shortest among them):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

where each step is just using your definition每一步都只是使用你的定义

I hope you are able to do the same for the other cases as well :D我希望你也能对其他情况做同样的事情:D


note that I use the simple trick of replacing:请注意,我使用了简单的替换技巧

  • : with findSubsequences :使用findSubsequences
  • [] with 0 (the first argument of `findSubsequences` ) [] with 0`findSubsequences`的第一个参数)

where you represent your input list as a:b:c:...:[]您将输入列表表示为a:b:c:...:[]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM