简体   繁体   中英

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

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 (<$) = 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 ()

Or more elegantly:

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

Or a more elegant version - commented by @Alec :

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

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

The answer provided by Willem Van Onsem is very good, I would just like to suggest the use of a language extension that can easily create Functor instances for newtypes: DeriveFunctor .

At the top of your module you can add:

{-# LANGUAGE DeriveFunctor #-}

Then you can automatically derive your Functor instance:

newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor

Here's is how I would find out the type of 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM