Haskell不动点签名
以下Haskell函数的签名是什么:Haskell不动点签名,haskell,functional-programming,Haskell,Functional Programming,以下Haskell函数的签名是什么: fix f = f (fix f) a) ((a->b)->a->b)->a->b b) 签名无法合成 c) (a->a)->a 谢谢 这个问题看起来像是一个课程作业/测试问题。我将帮助您自己找到解决方案: 首先,您可能安装了GHC,因此可以运行haskell repl 有。但它相当长 如果启动GHCi,将出现一个提示,您可以在其中键入Haskell表达式: Prelude> 1 + 1 2 Prelude> map (\x -> x +
fix f = f (fix f)
a) ((a->b)->a->b)->a->b
b) 签名无法合成
c) (a->a)->a
谢谢 这个问题看起来像是一个课程作业/测试问题。我将帮助您自己找到解决方案: 首先,您可能安装了GHC,因此可以运行haskell repl 有。但它相当长 如果启动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
这就是你如何找到解决问题的方法。知道这一点后,您可以问为什么修复的类型是这样的。一种完全不同的方法:通过推理找到解决方案 右手边是
f (fix f)
因此,对于某些类型的a
和b
,f具有类型a->b
,因为f
是一个函数
换句话说,f(fixf)
的值具有类型b
,而fixf
具有类型a
因为根据定义
fix f = f (fix f)
fix f
必须具有与f(fix f)
相同的类型,即b
我们已经说过a
是fixf
的类型,因此a
和b
必须是同一类型
让我们称之为t
来保持事物的独立性
因此f:t->t
,因为a
和b
是同一类型t
我们知道
fixf
的类型为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)几乎是正确的,但不够笼统。你可以试着把它放在REPL中,自己看看。更具体地说,在GHCi中定义
fix
,使用let fix f=f(fix f)
,然后用:t fix
询问它的类型。我投票结束这个问题,因为我也不想做你的家庭作业。可能重复为什么你不停在fix:(t->t)->t
。这是正确且主要的HM类型,它等于(模重命名)c)。若问题是多项选择题,我认为a)和c)都是正确的。或者任何一个都可以(任何正确的类型)。@phadej我确实在这里停了下来,但我编辑了一下,希望能让它更清楚一点。最后的旁白是为了解释备选方案a)不够笼统。