所以我让这些函数交换函数的参数
swap1_3 f x y z = f z y x
toFront3 f x y z = f z x y
这些功能如下工作
foo x y z = [x,y,z]
a = foo 1 2 3 -- returns [1,2,3]
b = swap1_3 foo 1 2 3 -- returns [3,2,1]
c = toFront3 foo 1 2 3 -- returns [3,1,2]
现在,我不明白的是这些功能的类型签名。
类型签名如下
swap1_3 :: (a -> b -> c -> d) -> c -> b -> a -> d
toFront3 :: (a -> b -> c -> d) -> b -> c -> a -> d
只是看着
swap1_3
有人会认为
a corresponds to the type of x
b corresponds to the type of y
c corresponds to the type of z
d corresponds to the return type of f
但是,当你看到
的类型签名的后半部分时toFront3
好像没有那种对应关系。
那么,这里发生了什么?
答案 0 :(得分:5)
这有点令人困惑,但这样看待它
f :: a -> b -> c -> d
f z :: b -> c -> d
f z x :: c -> d
f z x y :: d
暗示
z :: a
x :: b
y :: c
所以,我们有
toFront3
:: (a -> b -> c -> d) -- f
-> b -- x
-> c -- y
-> a -- z
toFront3 f x y z = f z x y
答案 1 :(得分:2)
toFront3 :: (a -> b -> c -> d) -> (b -> c -> a -> d)
也就是说,toFront3
采用3个参数的函数,并以不同的顺序为您提供相同参数的函数。
有一些名字:
let g = toFront3 f
g
和f
都是3个参数的函数。 g
将第3个参数拖到前面后将调用f
。因此,g
将收到的参数是预先洗牌的参数。因此,要从f :: a -> b -> c -> d
转到g
类型,我们必须应用toFront3
所做的参数的逆混洗,以便对它们进行混洗将恢复参数订购a -> b -> c -> d
,需要传递给f
后洗牌。