为什么这些Haskell函数有这些类型?

时间:2016-09-01 18:32:32

标签: haskell types functional-programming

有人可以解释为什么这两个函数有这些类型吗?我想我得到的第一个应该强制g的返回值与x相同,因为(gy)在函数参数中x的位置对应的let的位置,但似乎在第二个功能中,它不能像那样工作。

f3 g x = let h y = f3 g (g y) in g x  
(t -> t) -> t -> t  
f4 g x = let h y = f4 g (g y) in x  
(t1 -> t) -> t -> t

2 个答案:

答案 0 :(得分:3)

f3是两个参数的函数,因此具有类型t2 -> t1 -> t。由于函数的结果是g x,因此类型为tg本身必须是一个参数的函数,x类型为t1,因此g的类型为t2 = t1 -> t。未使用的h y定义要求g接受其结果类型作为导致t1 = t的参数类型。这将导致(t -> t) -> t -> t

f4也是两个参数的函数,因此具有类型t3 -> t2 -> t。由于它只返回xt2必须等于th y的定义 将g y约束为t2类型t,但不对y的类型设置约束,让我们调用t1。这导致t1 -> t作为g的类型。替换等式然后导致(t1 -> t) -> t -> t

答案 1 :(得分:2)

f3 g x = let h y = f3 g (g y) in g x

让我们先看一个更简单的版本:

f3' g x = g x

此处g已应用于xg的结果将成为f3'的结果。因此f3'的类型为(a -> b) -> a -> b

完整的f3包含子表达式f3 g (g y),它引入了一些额外的约束:f3 g是无害的(没有其他约束,因为g是我们调用的参数在开头),但(正如你在你的问题中所说)传递g y作为第二个参数意味着g的结果必须与x的结果相同(第二个参数)

这意味着a = b,因此f3 :: (a -> a) -> a -> a

在你的第二个例子中我们有

f4 g x = let h y = f4 g (g y) in x

没有let,它只是:

f4' g x = x

,其类型为a -> b -> b

完整f4包含f4 g (g y)。首先,这意味着g必须是一个函数(因为它应用于y),所以我们的约束集如下所示:

f4 :: a -> b -> b
g :: a
x :: b
g :: c -> d
a = c -> d

然后(g y)被用作f4的第二个参数,这意味着它的类型必须等于b

g y :: b
g :: c -> b
y :: c
d = b

h未被使用,因此yf4没有附加限制。替换f4类型的变量,我们得到

f4 :: (c -> b) -> b -> b

(相当于(t1 -> t) -> t -> t模数命名)。