haskell函数签名

haskell函数签名,haskell,signature,type-variables,Haskell,Signature,Type Variables,我对haskell中的类型签名有疑问。阅读有关applicative functor的内容,我发现: pure (+) <*> Just 3 这意味着在上面的例子中,我们的fb是用Maybe替换f和b替换a->a得到的 在这里,我有点惊讶,因为据我所知,b无法与a->a统一(如果我没有使用指定的术语,很抱歉,但我希望它们足够清晰) 这可能仅仅是因为我们在应用函子中,或者我缺少了其他东西吗?:t pure(+)是 (<*>) :: Applicative f =>

我对haskell中的类型签名有疑问。阅读有关applicative functor的内容,我发现:

pure (+) <*> Just 3 
这意味着在上面的例子中,我们的
fb
是用
Maybe
替换
f
b
替换
a->a
得到的

在这里,我有点惊讶,因为据我所知,
b
无法与
a->a
统一(如果我没有使用指定的术语,很抱歉,但我希望它们足够清晰)

这可能仅仅是因为我们在应用函子中,或者我缺少了其他东西吗?

:t pure(+)

 (<*>) :: Applicative f => f (a -> b) -> f a -> f b
pure (+) :: (Num a, Applicative f) => f (a -> a -> a)
注意
f(a->a->a)

既然
:t()

(<*>) :: Applicative f => f (a -> b) -> f a -> f b
()::应用程序f=>f(a->b)->f a->f b
f(a->b)
实际上是a
f(a->a->a)

因此,本例中的类型变量
b
a->a
b
是一个(n个无约束的)类型变量,因此它可以始终与每种类型统一。它与
Applicative
函子无关,只要类型变量必须与类型统一,它就可以工作


大致上,统一两个类型表达式会产生最通用的类型表达式,它并不比统一的任何一个伙伴更通用。如果两个类型表达式中的一个表达式比另一个表达式更通用,则统一总是成功的,并导致统一的更具体的伙伴。所有类型表达式中最通用的是一个没有任何结构的类型表达式,即类型变量。因此,通过使用类型表达式实例化类型变量,可以将类型变量与任何类型表达式统一(如果类型匹配,类型为
*
的类型变量当然不能与类型表达式统一
可能
而类型为
*->*
)因此,这意味着没有约束的函数的每个类型签名都可以是
a
?类型,反之亦然。类型变量可以用每种类型实例化,可以是函数类型、列表类型、或
IO()
、或。如果类型变量受约束,则只有具有相关类实例的类型才符合条件。统一的结果并不总是比统一类型表达式更一般。因此,如果你把一个函数类型和某个东西统一起来,结果也是一个函数类型。类型变量是可能的最通用的类型表达式。好吧,我想我已经理解了,但在这种情况下,为什么我在执行类似
id':b
id'=id
的操作时会出现模糊错误,在这里,您的类型签名承诺
id'
可以包含所有类型,但实现提供了一个不太通用的类型,即
a->a
。(虽然我得到的
无法将预期的类型'b'与实际的类型'a0->a0'
匹配为错误,而不是
不明确的类型
)在这种情况下,实际的推断类型必须至少与类型签名指定的一样通用,因此统一的结果必须[直到重命名类型变量]与签名中给出的类型表达式完全相同。我不知道,现在终于明白了:)哦,
我得到的类型无法将预期的类型“b”与实际类型“a0->a0”匹配,这也是我的错误。