以下Haskell函数的签名是什么:
fix f = f (fix f)
a)((a-> b) - > a-> b) - > a-> b
b)签名无法合成
c)(a-> a) - > a谢谢!
答案 0 :(得分:6)
此问题看起来像课程作业/测试问题。我会帮你自己找到解决方案:
首先你可能安装了GHC,所以你可以运行ghci
一个haskell repl。
有a section in GHC users' guide about GHCi。但它很长。
如果你启动GHCi,你会得到一个提示,你可以输入Haskell表达式:
Prelude> 1 + 1
2
Prelude> map (\x -> x + x) [1, 2, 3]
[2,4,6]
您还可以将表达式绑定到名称,并定义函数:
Prelude> let fix f = f (fix f)
最强大的功能之一是询问表达式的类型:
Prelude> :t map (\x -> x + x)
map (\x -> x + x) :: Num b => [b] -> [b]
Prelude> :t fix
... output omitted
这就是您找到解决问题的方法。在您知道之后,您可以问为什么fix
的类型就是它。
答案 1 :(得分:2)
一种完全不同的方法:通过推理找到解决方案。
右侧是
f (fix f)
所以f
的某些类型a -> b
和a
的类型为b
,因为f
是一个函数。
换句话说,f (fix f)
的值的类型为b
,fix f
的类型为a
。
根据定义,
fix f = f (fix f)
fix f
必须与f (fix f)
具有相同的类型,即b
。
我们已经说a
是fix f
的类型,因此a
和b
必须是同一类型。
我们称之为t
以保持分开。
所以f : t -> t
,因为a
和b
属于同一类型t
。
我们知道fix f
的类型为b
,我们将其重命名为t
。
将f : t -> t
和fix f : t
放在一起我们得到了
fix : (t -> t) -> t
这是替代c)。
除此之外:如果我们将a -> b
替换为t
,我们会得到
((a -> b) -> (a -> b)) -> (a -> b)
或者,因为箭头与右侧相关联:
((a -> b) -> a -> b) -> a -> b
这正是a)中的答案 所以a)几乎是正确的,但不够通用。