I am learning Haskell. I have a list that looks like this:
data TwoValueList a = Empty | Node a a (TwoValueList a)
I wish to make this Foldable
, such that I might be able to do computations like:
sum (Node 0 1 (Node 2 3 Empty)) --should produce 6
If there were only one value, it would be easy:
data OneValueList = Empty | Node a (OneValueList a)
instance Foldable OneValueList where
foldr f b Empty = b
foldr f b (Node a rest) = f a (foldr f b rest)
However, if there are two values inside one node, I can't finegle the types because f
takes a
and b
, but I must apply f
to both a
s inside of the TwoValueList
and combine them somehow. Am I missing some other type constraint?
Thank you.
CodePudding user response:
data TwoValueList a = Empty | Node a a (TwoValueList a)
instance Foldable TwoValueList where
foldr _ ini Empty = ini
foldr f ini (Node x y xs) = f x $ f y $ foldr f ini xs
The way this works is that foldr
calls itself recursively on recursive instances of TwoValueList
that are embeded in each other up until it meets Empty
. At that point it returns ini
which is the initial value and the call stack comes up resolving all the function calls further above.
CodePudding user response:
Just call f
twice and give one value to each call: foldr f b (Node x1 x2 xs) = f x1 (f x2 (foldr f b xs))
.