Search code examples
haskellfunctormap-function

How to understand functor in \g x -> fmap ($) g x


I am a beginner to Haskell. I know that the function fmap takes two arguments ((a->b) -> f a ->) and returns a functor (f b), but I cannot understand the following lambda expression

*Main> :t \g x -> fmap ($) g x
\g x -> fmap ($) g x :: (t -> a -> b) -> t -> a -> b

where is the functor?

Btw, I have tried several similar expression with different brackets, which give different results:

*Main> :t \g x -> fmap ($) (g x)
\g x -> fmap ($) (g x) :: Functor f => (t -> f (a -> b)) -> t -> f (a -> b)

*Main> :t \g x -> fmap $ g x
\g x -> fmap $ g x :: Functor f => (t -> a -> b) -> t -> f a -> f b

I don't understand this.


Solution

  • From

    \g x -> fmap ($) g x :: (t -> a -> b) -> t -> a -> b
    

    we have

    g            :: t -> a -> b
    x            :: t
    fmap ($) g   :: t -> a -> b
    fmap ($) g x :: a -> b
    

    To find the functor, it suffices to write the type of g as the type-level application F X for some F and X.

    We have

    t -> a -> b    =    (->) t (a -> b)
    

    hence, F = (->) t and X = (a -> b).

    Therefore, the fmap call works in the (->) t functor. We need to think to t -> a -> b as a value of type a -> b "wrapped" under the functor (->) t.

    Now, we have

    ($) :: (a->b) -> a -> b
    -- which means
    ($) :: (a->b) -> (a -> b)
    
    g   :: F (a->b)
    fmap ($) :: F (a->b) -> F (a->b)
    fmap ($) g :: F (a->b)
    -- i.e.
    fmap ($) g :: t -> (a->b)