我试图定义以下函数的多态类型:
flip f x y = f y x
我的想法如下:
flip
的第一个参数, f
需要两个参数,因此(t1 -> t2 -> t3)
flip
的第2个参数, x
的类型为 t1
,因为参数 { t1
功能内的{1}} 。
f
, flip
的第3个参数,其类型为 y
,因为参数 t3
功能内的t3
。
我不知道整体回报的多态类型。
但是当我检查ghci中的类型时,我得到:
f
有人请帮助通过这个例子说明这里发生了什么?
由于
答案 0 :(得分:5)
第二个假设错误:
翻转的第二个参数,由于f函数内的参数t1,x的类型为t1。
让我们先分析一下这个功能:
flip f x y = f y x
我们看到flip
头部有三个参数。所以我们先做类型:
flip :: a -> (b -> (c -> d))
我们当然现在的目标是填写类型。用:
f :: a
x :: b
y :: c
flip f x y :: d
我们在右侧看到:
(f y) x
这意味着f
是一个作为输入y
的函数。这意味着a
与c -> e
(或更短a ~ c -> e
)的类型相同。
现在:
flip :: (c -> e) -> (b -> (c -> d))
f :: (c -> e)
x :: b
y :: c
此外,我们看到:
(f x) y
因此(f x)
的结果是另一个函数,输入为y
。这意味着e ~ b -> f
。因此:
flip :: (c -> (b -> f)) -> (b -> (c -> d))
f :: c -> (b -> f)
x :: b
y :: c
最后,我们发现(f y) x
是flip f x y
的结果。这意味着(f y) x
的结果类型与d
的类型相同。这意味着f ~ d
。这意味着:
flip :: (c -> (b -> d)) -> (b -> (c -> d))
或者,如果我们删除一些冗余括号:
flip :: (c -> b -> d) -> b -> c -> d
答案 1 :(得分:2)
这只是解决方程组的问题。首先,分配未知类型:
f : a1
x : a2
y : a3
接下来,f
将应用于y
。因此,f
必须是一个函数类型,其参数类型与y相同,即
f : a1 = a3 -> a4
f y : a4
类似地,f y
已应用于x
,因此
f y : a4 = a2 -> a5
f y x : a5
替换回来,我们得到
f : a3 -> a2 -> a5
x : a2
y : a3
我们可以重命名这些类型
t2 = a3
t1 = a2
t = a5
并获取
f : t2 -> t1 -> t
x : t1
y : t2
函数正文为f y x
,其类型为t = a5
。