This works fine:
data Foo a = Foo a
instance Functor Foo where
fmap f (Foo s) = Foo (f s)
This throws an Error:
data Foo = Foo String
instance Functor Foo where
fmap f (Foo s) = Foo (f s)
Error:
Kind mis-match The first argument of `Functor' should have kind `* -> *', but `Foo' has kind `*' In the instance declaration for `Functor Foo'
What am I missing here? Why can’t I use functors to wrap and unwrap Foo
if it holds a specific type?
UPDATE
I guess I can ask this another way:
data Foo = Foo String deriving(Show)
let jack = Foo "Jack"
-- Some functory thingy here
putStrLn $ show $ tail <$> jack
-- Foo "ack"
Why can't I do this? Or is there another construct for this use case?
That's because Foo
needs a single type variable to operate on.
The type of fmap
is:
fmap :: Functor f => (a -> b) -> f a -> f b
Now try to specialize this for your Foo
:
(a -> b) -> Foo -> Foo
Can you see where the problem is ? The types won't just match. So, to make Foo
a functor, it has to be something like this:
Foo a
so that when you specialize it for fmap it has the following proper type:
(a -> b) -> Foo a -> Foo b
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