Recursion over lists in Haskell?

First let's consider that function f that you have. It takes some sort of accumulated value, a plain value, and combines them into a result. So, in the type signature, we'll say a for the type of the accumulated value v for the type of the value, and r for the type of the result f :: a -> v -> r Now we want to create a folding function that uses f and a list of values someFold :: (a -> v -> r) -> v ->?

What should it return? It should yield something of the resultant type r right? Notice now that a and r should actually be the same type, since we keep feeding the result of f into it's first argument again someFold :: (a -> v -> a) -> v -> a Now one thing's missing.

How do you get the very first a? There are two ways to look at that. Either you just pick the first value, in which case a is the same type as v or you specify a base value, so a could actually be different than v Let's go with the latter, since that's more interesting.

Let's also decide to move left to right in this list. (That's what you need, right? ) someFold :: (a -> v -> a) -> a -> v -> a So...how do we implement it?

It'll be recursive, so let's start with the base cases someFold f acc = acc If we hit the end of the list, then we've accumulated enough, right? That was easy. So how about the recursive case?

From what you said, at each step we should apply f to the "accumulated value so far" as the first argument, and the "first value of the list" as the second f acc x Then we keep folding, using that as our new "accumulated" value someFold f acc (x:xs) = someFold f (f acc x) xs Easy, right? But...what if we want to do like you said and start the function by taking the first two values of the list? Also easy.

Just take the first element, and call it the original "base" accumulator! SomeFold1 :: (v -> v -> v) -> v -> v someFold1 f (x:xs) = someFold f x xs Notice that since a is the same type as v for this special case, the function someFold1 has a very amusing type signature. If you understood this explanation, then congrats.

We've just implemented foldl and foldl1 Prelude> foldl1 min "abcde" -- "abcde" is sugar for 'a','b','c','d','e' 'a In real code, you should actually use foldl and friends.

First let's consider that function f that you have. It takes some sort of accumulated value, a plain value, and combines them into a result. So, in the type signature, we'll say a for the type of the accumulated value, v for the type of the value, and r for the type of the result.

F :: a -> v -> r Now we want to create a folding function that uses f and a list of values. SomeFold :: (a -> v -> r) -> v ->? What should it return?

It should yield something of the resultant type r, right? Notice now that a and r should actually be the same type, since we keep feeding the result of f into it's first argument again. SomeFold :: (a -> v -> a) -> v -> a Now one thing's missing.

How do you get the very first a? There are two ways to look at that. Either you just pick the first value, in which case a is the same type as v, or you specify a base value, so a could actually be different than v.

Let's go with the latter, since that's more interesting. Let's also decide to move left to right in this list. (That's what you need, right?) someFold :: (a -> v -> a) -> a -> v -> a So...how do we implement it?

It'll be recursive, so let's start with the base cases. SomeFold f acc = acc If we hit the end of the list, then we've accumulated enough, right? That was easy.

So how about the recursive case? From what you said, at each step we should apply f to the "accumulated value so far" as the first argument, and the "first value of the list" as the second. F acc x.

Then we keep folding, using that as our new "accumulated" value. SomeFold f acc (x:xs) = someFold f (f acc x) xs Easy, right?But...what if we want to do like you said and start the function by taking the first two values of the list? Also easy.

Just take the first element, and call it the original "base" accumulator! SomeFold1 :: (v -> v -> v) -> v -> v someFold1 f (x:xs) = someFold f x xs Notice that since a is the same type as v for this special case, the function someFold1 has a very amusing type signature. If you understood this explanation, then congrats.

We've just implemented foldl and foldl1. Prelude> foldl1 min "abcde" -- "abcde" is sugar for 'a','b','c','d','e' 'a' In real code, you should actually use foldl' and friends.

Thanks, this is what I was trying to understand. – thetux4 Mar 17 at 9:10.

Sounds like homework. Take a look at folds.

Since i'm a newbie in functional programming, and there is no looping in haskell, its a little bit hard to get used to it. Well folds may work, thanks. – thetux4 Mar 16 at 20:36 2 Folds are in fact the basic "looping" mechanism in functional languages.

Learn them and it'll take you a long way. – geekosaur Mar 16 at 20:40 1 -1 While I agree that homework questions should not be answered outright, I also think that answers should be helpful and try to dig into the problem a little. – luqui Mar 17 at 2:11.

In this case, the problem with a fold is, that it usually processes on element at a time. You could try to manually roll a fold. Assume, you have your function f, that gets two elements at a time and the accumulator (the result of the last iteration) fed.

Then you function looks like this: fold2 :: (a -> a -> be -> b) -> a -> be -> be fold2 f accum (x:y:zs) = fold2 f (f x y) zs fold2 _ accum = accum fold2 _ _ _ = error "odd number of elements" Try to understand this. Fold2 shaves the top two elements of the list of and feeds it into f. The result this is then passed as the new accumulator to the recursive call.

This is done until the list is empty.

Ok I got this. But I have another problem here. Inside the fold the return value of f(x y) is not the same type as in the list.

For instance I have chars in the list, but f returns int type. – thetux4 Mar 16 at 21:06 Ah! I kind of misinterpreted your question.

I thought you want to feed two elements at a time into f. Oops... I'm going to remove this answer then. – FUZxxl Mar 16 at 21:11 Actually the scenario is like this: f (g x) (g y) -> I first send the two elements x and y to g then their result to f.

Then I want to send third element also like g head(xs). And its like f( (f (g x) (g y) ) head(xs) ). – thetux4 Mar 16 at 21:41.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions