简化Haskell型签名

简化Haskell型签名,haskell,types,Haskell,Types,我的问题是如何分析处理Haskell类型签名。为了使其具体化,我正在研究“修复”函数: fix :: (a -> a) -> a 还有一个我写的用来做花生加法的小函数: add = \rec a b -> if a == 0 then b else rec (a-1) (b+1) 当我检查类型时,我得到了fix add的预期类型: fix add :: Integer -> Integer -> Integer 而且它似乎像我期望的那样工作: > (fi

我的问题是如何分析处理Haskell类型签名。为了使其具体化,我正在研究“修复”函数:

fix :: (a -> a) -> a
还有一个我写的用来做花生加法的小函数:

add = \rec a b -> if a == 0 then b else rec (a-1) (b+1)
当我检查类型时,我得到了
fix add
的预期类型:

fix add :: Integer -> Integer -> Integer
而且它似乎像我期望的那样工作:

> (fix add) 1 1
2

如何使用
fix
add
的类型签名来显示
fix add
具有上述签名?如果“代数”这个词是正确的,那么使用类型签名的规则是什么?我怎样才能“展示我的作品”

ghci
告诉我们

add::Num a=>(a->a->a)->a->a->a

对某些类型类噪波进行模化,因为
add
的第二个参数需要一个
Eq
实例(您正在检查它是否与
0
相等)

当我们将
fix
应用于
add
时,
fix
的签名变为

fix::((a->a->a)->(a->a->a))->(a->a->a)

请记住,
fix:(a->a)->a
中的
a
s可以具有任何类型。在这种情况下,它们的类型为
(a->a->a)

因此,
fixadd::numa=>a->a->a
,这正是添加两个
a
s的正确类型


您可以以非常代数的方式使用Haskell的类型签名,变量替换的工作方式与您预期的一样。事实上,类型和代数之间有着直接的联系。

谢谢!我已经计算出了很多(在
fix
a
必须是
(a->a->a)
)。但难道一步也没有走完吗?在
((a->a->a)->(a->a->a))->(a->a->a)
a->a
之间是否存在某种中间环节?是的,您部分地将
fix
应用于
add
。结果部分应用的函数具有类型
a->a
@twopoint718将
fix
应用到
add
会从
fix
的类型中删除
((a->a->a->a))
参数。@GabrielGonzalez谢谢,我想这样做了。我现在明白了。谢谢大家。