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