如何理解 \g x -> fmap ($) g x 中的仿函数

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

我是 Haskell 的初学者。我知道函数 fmap 有两个参数 ((a->b) -> f a ->) 和 returns 一个仿函数 (f b),但我无法理解下面的 lambda 表达式

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

仿函数在哪里?

顺便说一句,我已经尝试了几个不同括号的相似表达式,它们给出了不同的结果:

*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

我不明白这个。

来自

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

我们有

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

要找函子,写g的类型作为类型级的应用F X就可以了FX.

我们有

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

因此,F = (->) tX = (a -> b)

因此,fmap 调用在 (->) t 函子中起作用。我们需要将 t -> a -> b 视为 a -> b 类型的值“包装”在函子 (->) t.

现在,我们有

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

首先,正如您所说,我们有

fmap :: Functor f 
     => (  a    ->   b   ) -> f a -> f b
($)  ::  (t->s) -> t -> s
g    ::                       f a
     ~                        f (t->s)
-----------------------------------------   a ~ (t->s) ~ b
fmap ($) g ::                        f b
           ~                         f (t->s)

然后将其应用于 x... 但只有 函数 应用于参数:

fmap ($) g :: Functor f        => f    (t->s)
           ~  Functor ((->) c) => c -> (t->s)
           x                   :: c
----------------------------------------------   f ~ ((->) c)
fmap ($) g x                   ::      (t->s)

事实上 ((->) c) 是一个函子。因此,对 x 的应用是选择特定 Functor 类型,函数的 Functor。

综合起来,

--                         g             x
\g x -> fmap ($) g x :: (c -> (t->s)) -> c -> (t->s)

-- compare with
        fmap ($)     ::  f    (t->s)  -> f    (t->s)   -- Functor (f ~ ((->) c)
        fmap id      ::  f    q       -> f    q
        id           ::  r            -> r

事实上,($) 只是一个更特殊的 idfmap id === id,根据 Functor Laws。由于所有额外的参数/实例化为其提供了更多上下文,该类型变得更加专业化。