I want to implement foldable for
data Constant a b = Constant a
This is my straightforward attempt:
instance Foldable (Constant a) where
foldr f b (Constant a) = f a b
The part of the compilation error I want to understand is:
Couldn't match expected type ‘a1’ with actual type ‘a’
‘a1’ is a rigid type variable bound by the type signature for
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
as you can see the folding function takes the "phantom type" (?) a1 from the Constant which I do not have access to; I only have access to the a.
How do I solve this? Please do explain your solution, because I am rather confused.
The whole compilation error is:
try2/chap20/ex1.hs:9:30: Couldn't match expected type ‘a1’ with actual type ‘a’ …
‘a’ is a rigid type variable bound by
the instance declaration
at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:8:10
‘a1’ is a rigid type variable bound by
the type signature for
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:3
Relevant bindings include
a :: a
(bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:23)
f :: a1 -> b -> b
(bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:9)
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
(bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:3)
In the first argument of ‘f’, namely ‘a’
In the expression: f a b
Compilation failed.
Constant a b doesn't contain any b-s, so we fold over it as if it were an empty list of b-s:
instance Foldable (Constant a) where
foldr f z (Constant a) = z
a in Constant a b is not relevant to the Foldable instance, since that only concerns the last parameter. Hence you can't really make use of a in your definition.
I think the only possibility is:
data Constant a b = C a
-- foldMap :: Monoid m => (b -> m) -> t b -> m
instance Foldable (Constant a) where
foldMap f (C a) = mempty
which is the trivial solution.
It might be instructive to see why you can do it for this definition:
data Constant' a b = C' b
-- foldMap :: Monoid m => (b -> m) -> t b -> m
instance Foldable (Constant' a) where
foldMap f (C' a) = f a
Here t is Constant' a, so
t b is Constant' a b. Values of this type have the structure C bval for some value bval of type b.f has type b -> m, so we can apply f to bvalIn the other case, though, we don't have a value from b to apply to f, so the best we can do is return mempty.
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