[英]How to understand functor in \g x -> fmap ($) g x
我是 Haskell 的初学者。 我知道 function fmap
需要两个 arguments ( (a->b) -> fa ->
)并返回一个仿函数( fb
),但我无法理解以下 Z945F3FC449518A73B9F5F328CZ 表达式
*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 = (->) t
和X = (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
... 但仅将函数应用于 arguments:
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
事实上($)
只是一个更专业的id
,而fmap id === id
,由仿函数定律。 由于所有额外的 arguments / 实例化为它提供了更多上下文,因此该类型变得更加专业。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.