Executor instance
I have the following type newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a }
. And I have to write a Functor instance for it, but I really don't 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 leads to the type
(a -> b) -> Arr2 e1 e2 a -> b
instead of the desired
(a -> b) -> Arr2 e1 e2 a -> Arr2 e1 e2 b
So please help me
source to share
The class Functor
has a definition:
class Functor f where:
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
(<$)
has a standard implementation: (<$) = fmap . const
which works great.
So this means that if we enter a function ( g :: a -> b
) as the first argument and Arr2
that creates a
, we have to generate Arr2
one that calls this g
on the result of the arrow, if applied.
As a result, the definition fmap
for your Arr2
:
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 zero-free using this tool )
source to share
The answer, provided of Willem Van Onsem , very good, I would suggest using a language extension, which can easily create instances of Functor
new types DeriveFunctor
.
At the top of the module, you can add:
{-# LANGUAGE DeriveFunctor #-}
Then you can get the instance automatically Functor
:
newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor
This is how I would find out the type fmap
for this instance in GHCi:
λ > :set -XDeriveFunctor
λ > newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor
λ > :set -XTypeApplications
λ > :t fmap @(Arr2 _ _)
fmap @(Arr2 _ _) :: (a -> b) -> Arr2 t t1 a -> Arr2 t t1 b
source to share