Haskell定点签名

时间:2015-02-02 07:53:04

标签: haskell functional-programming

以下Haskell函数的签名是什么:

fix f = f (fix f)

a)((a-> b) - > a-> b) - > a-> b

b)签名无法合成

c)(a-> a) - > a

谢谢!

2 个答案:

答案 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 -> ba的类型为b,因为f是一个函数。

换句话说,f (fix f)的值的类型为bfix f的类型为a

根据定义,

fix f = f (fix f)

fix f必须与f (fix f)具有相同的类型,即b

我们已经说afix f的类型,因此ab必须是同一类型。

我们称之为t以保持分开。

所以f : t -> t,因为ab属于同一类型t。 我们知道fix f的类型为b,我们将其重命名为t

f : t -> tfix f : t放在一起我们得到了

fix : (t -> t) -> t  

这是替代c)。


除此之外:如果我们将a -> b替换为t,我们会得到

((a -> b) -> (a -> b)) -> (a -> b)

或者,因为箭头与右侧相关联:

((a -> b) -> a -> b) -> a -> b

这正是a)中的答案 所以a)几乎是正确的,但不够通用。