Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functors don’t work with data types that require specific types

Tags:

haskell

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?

like image 820
Fresheyeball Avatar asked Nov 30 '22 00:11

Fresheyeball


1 Answers

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
like image 163
Sibi Avatar answered Dec 05 '22 02:12

Sibi