我对haskell中的类型签名有疑问。阅读应用函子,我发现:
pure (+) <*> Just 3
返回Just (+3)
类型Maybe (a->a)
。现在<*>
的签名是
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
这意味着上面示例中的f b
取代f
替换为Maybe
而b
替换为a->a
。
在这里,我有点惊讶,因为就我所知,b
无法统一(抱歉,如果我没有使用指定的术语,但我希望它们足够清楚)与a->a
。
这是否可能只是因为我们在内部和应用程序的操作者或者我还缺少其他东西?
答案 0 :(得分:11)
b
是一个(n无约束)类型变量,因此它可以始终与每个类型统一。它与Applicative
仿函数无关,只要类型变量必须与类型统一,它就可以工作。
粗略地说,统一两个类型表达式会导致最一般的类型表达式不是统一的任何一个伙伴。如果两个类型表达式中的一个比另一个更通用,则统一总是成功并且导致统一的更具体的伙伴。所有类型表达式中最常见的是一个没有任何结构的表达式,一个类型变量。因此,通过使用该类型表达式实例化类型变量,类型变量可以与任何类型表达式统一(假设种类匹配,类型变量的类型*
当然不能与类型表达式{{1 } whise kind是Maybe
)。
答案 1 :(得分:7)
:t pure (+)
是
pure (+) :: (Num a, Applicative f) => f (a -> a -> a)
请注意f(a -> a -> a)
因为:t (<*>)
是
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
f ( a -> b)
实际上是f ( a -> a -> a)
。
因此,在这种情况下的类型变量b
是 a -> a