用于交换函数参数的函数类型

时间:2014-04-29 22:26:35

标签: haskell types functional-programming

所以我让这些函数交换函数的参数

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
好像没有那种对应关系。

那么,这里发生了什么?

2 个答案:

答案 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

gf都是3个参数的函数。 g将第3个参数拖到前面后将调用f。因此,g将收到的参数是预先洗牌的参数。因此,要从f :: a -> b -> c -> d转到g类型,我们必须应用toFront3所做的参数的混洗,以便对它们进行混洗将恢复参数订购a -> b -> c -> d,需要传递给f后洗牌。