Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using foldr in elm/haskell

Tags:

haskell

fold

elm

I'm having trouble solving this problem using foldr. I understand foldr for simple problems (like foldr (+) 5 [1,2,3,4]) but this is more complicated:

Question: What is the value of 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. Help would be appreciated :)

like image 350
Chloe Avatar asked Dec 15 '22 10:12

Chloe


2 Answers

The r in foldr signifies that it is a right-associative fold.

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).

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.

Applying this to the last element of your tuple (renaming findSubsequence to f for brevity) results in:

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
like image 55
dkasak Avatar answered Dec 25 '22 12:12

dkasak


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 f a b instead of a `f` b where ever you find it


take one component of q2 (I'll take the last - because it's the shortest among them):

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


note that I use the simple trick of replacing:

  • : with findSubsequences
  • [] with 0 (the first argument of `findSubsequences`)

where you represent your input list as a:b:c:...:[]

like image 27
Random Dev Avatar answered Dec 25 '22 13:12

Random Dev