Search code examples
haskellfunctorapplicative

Implementing applicative functor for custom data type with two identical type classes


I'm trying to make Twice a member of applicative, but I am getting "Conflicting definitions for `a'" in the functor implementation: Also I'm not sure how to implement the <*> correctly :/

data Twice a = Twice a a deriving (Show)

instance Functor Twice where
    fmap f (Twice a a) = Twice (f a) (f a)

instance Applicative Twice where
    pure x = (Twice x) x
    Twice f f <*> Twice x x = Twice ((f x) (f x))

Solution

  • The errors are more syntactical than semantical I guess. In your definition:

    Twice f f <*> Twice x x = Twice ((f x) (f x))

    the same in the Functor defintion:

    fmap f (Twice a a) = Twice (f a) (f a)

    You write two fs and two x's in the head. Haskell does not allows that (Prolog does, but even then it is probably not what you mean).

    Furthermore in the body you write:

    ((f x) (f x))

    This means that you would make a function call with f x the function, and f x the argument, which is again probably not what you intended.

    We can fix it syntactically to:

    instance Functor Twice where
        fmap f (Twice a b) = Twice (f a) (f b)
    
    instance Applicative Twice where
        pure x = Twice x x
        Twice f g <*> Twice x y = Twice (f x) (g y)

    Note that you still need to prove that this is a valid Functor and Applicative instance by taking the constraints documented for these typeclasses into account.