Search code examples
haskellfunctor

instance Functor with data


i am new to Haskell but i implemented this:

data Triple = T Double Double Double

instance Functor Triple where
    fmap f (T a b c) = T (f a) (f b) (f c)

then i tried to make the Triple a Functor but i get this message:

**error:
    • Expected kind ‘* -> *’, but ‘Triple’ has kind ‘*’
    • In the first argument of ‘Functor’, namely ‘Triple’
      In the instance declaration for ‘Functor Triple**’

so my question is , do i really have to change the data Constructor to

data Triple a = a a a

???

this is my solution but is there a better one ?


Solution

  • yes, you need a * -> * Type for a Functor.

    It has to be like this as the type of fmap is fmap :: (a -> b) -> f a -> f b - so as you can see f is applied to the type-parameter a in there.

    So yep this would work:

    data Triple a = T a a a
    
    instance Functor Triple where 
        fmap f (T a b c) = T (f a) (f b) (f c)
    

    * -> * means you need a type-constructor that is waiting for a Type and returns a Type.

    For example:

    • Double has kind *
    • Triple(here) has kind * -> *
    • Triple Double has kind * again

    it's like a curried function on the type-level ;)


    you could write something like this for your Triple though:

    data Triple = T Double Double Double
    
    tripleMap :: (Double -> Double) -> Triple -> Triple
    tripleMap (T a b c) = T (f a) (f b) (f c)
    

    and maybe this is fine enough for you.