在 Haskell 中,(<*>)
的默认实现Control.Applicative 中的运算符(它将函数 a->b
的应用程序应用于 a
的应用程序,从而产生 b
的应用程序)。
(<*>) :: 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
代表什么类型),并详细说明它如何产生一个函数,该函数采用函数的应用程序和值的应用程序并应用它们,我将非常感激。
最佳答案
假设 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
,这正是 <*>
的类型(模数重命名)。
关于haskell - Haskell 中 (<*>) 的默认定义是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47065766/