Search code examples
haskellfunctor

Instance of a Functor


I have a following type newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a }. And I got to write Functor instance for it, yet i don't really understand how I tried

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (g a)

and

instance Functor (Arr2 e1 e2) where
  fmap g = g . getArr2

which actually results in type

(a -> b) -> Arr2 e1 e2 a -> b

instead of desired

(a -> b) -> Arr2 e1 e2 a -> Arr2 e1 e2 b

So please, help me


Solution

  • The Functor class has as definition:

    class Functor f where:
        fmap :: (a -> b) -> f a -> f b
        (<$) :: a -> f b -> f a
    

    The (<$) has a default implementation: (<$) = fmap . const which works fine.

    So that means that if we enter a function (g :: a -> b) as first argument, and an Arr2 that produces an a, we have to generate an Arr2 that calls that g on the outcome of the arrow if it is applied.

    As a result the definition of fmap for your Arr2 is:

    instance Functor (Arr2 e1 e2) where
      fmap g (Arr2 a) = Arr2 (\x y -> g (a x y))

    Or more elegantly:

    instance Functor (Arr2 e1 e2) where
      fmap g (Arr2 a) = Arr2 (\x -> g . (a x))

    Or a more elegant version - commented by @Alec:

    instance Functor (Arr2 e1 e2) where
      fmap g (Arr2 a) = Arr2 ((g .) . a)

    (you can convert expressions to pointfree ones using this tool)