他们之间有什么区别?
(i)
gen :: (a -> a -> a ) -> a -> a
gen f x = f x
(ii)
gen :: (a -> a ) -> a -> a
gen f x = f x
(iii)
gen :: (a -> a -> a -> a ) -> a -> a
gen f x = f x
第一个给出错误:“不能构建无限......”
第二个是工作
第三个不起作用
答案 0 :(得分:2)
让我们试着找出第一个函数的类型:
想象一下,a
为Int
,f
是正常添加。第二个参数是Int
。如果你打电话给gen (+) 3
,结果是一个等同于(+3)
的函数,它接受Int
并返回Int
。但是你的签名说你只需要回复Int
。
所以基本上编译器会抱怨因为它需要一个a
,你给它一个a->a
,并且没有办法统一这些类型。
要修复此问题,您可以更正签名,即gen :: (a -> a -> a ) -> a -> (a -> a)
,或更改定义,例如gen f x = f x x
第二个只是身份函数id :: t -> t
的特化。
第三个类似于第一个。