Haskell定点签名

Haskell fixed point signature

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

fix f = f (fix f)

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

b)无法合成签名

c) (a->a)->a

谢谢!

这道题看起来像是一道课程作业/试题。我会帮你自己找到解决方案:

首先你可能已经安装了 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 的类型是这样的。

完全不同的方法:通过推理找到解决方案。

右边是

f (fix f)

所以 f 对于某些类型 ab 具有类型 a -> b,因为 f 是一个函数。

换句话说,f (fix f) 的值具有 b 类型,而 fix 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) 几乎是正确的,但不够普遍。