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.
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.
I find it easier to just define the foldMap method instead:
data TwoValueList a = Empty | Node a a (TwoValueList a)
instance Foldable TwoValueList where
foldMap _ Empty = mempty
foldMap f (Node x y r) = f x <> f y <> foldMap f r
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With