在Haskell中,(<*>)
运算符的默认实现(它将函数a->b
的应用程序应用于a
的应用程序,从而导致b
的应用程序Control.Applicative定义为 -
(<*>) :: f (a -> b) -> f a -> f b
(<*>) = liftA2 id
我根本无法理解它是如何运作的。
liftA2
的类型为liftA2 :: (a -> b -> c) -> f a -> f b -> f c
,这意味着它需要一个二进制函数,id
不是。根据我的理解,这意味着id
在某种程度上被解释为更复杂的类型 - 但我不确定它使这个定义起作用的方式和方式。如果有人可以解释可能解释的id
类型是什么类型(a
定义中的id :: a -> a
代表什么类型),并且还要介绍它如何产生一个函数,该函数采用了功能和价值观的应用并适用它们我会非常感激。
答案 0 :(得分:9)
我们说id
的类型是d -> d
,所以我们所有的类型变量都有不同的名称。现在让我们介绍两个新的类型变量e
和t
并说出d = e -> t
。这使得类型为id
:
id :: (e -> t) -> e -> t
现在,这符合liftA2
a = e -> t
,b = e
和c = t
的第一个参数的类型。因此,对于这些分配,liftA2
的类型变为:
liftA2 :: ((e -> t) -> e -> t) -> f (e -> t) -> f e -> f t
如果我们应用第一个参数,则剩余的类型变为f (e -> t) -> f e -> f t
,这正是<*>
的类型(模数重命名)。