Haskell:应用两次翻转(翻转翻转的类型)

时间:2019-01-29 20:15:59

标签: function haskell functional-programming

我正在通过一些基本功能来学习Haskell。我正在使用Flip进行一些练习,该函数具有两个参数的功能,并通过翻转参数的顺序来评估结果。考虑功能 flip flip ,我会认为,按照flip的定义,它会将参数翻转了两次,并以原始顺序使用参数评估了原始功能。当我用ghci检查函数类型检查这个假设时,它产生了:

flip flip :: b->(a-> b-> c)-> a-> c

我不明白为什么这是翻转翻转的功能类型。它接受参数b和参数(a-> b-> c),并产生函数a-> c。为什么会这样呢?由于我对此一无所知,因此我将不胜感激。预先感谢

3 个答案:

答案 0 :(得分:9)

翻转两次将是\f -> flip (flip f)flip . flip。确实的类型为(a -> b -> c) -> (a -> b -> c)

您在这里所做的是在flip函数上应用flip,即翻转flip的参数顺序。所以如果我们以

开始
flip :: (a -> b -> c) -> b -> a -> c
-- and, as the type of the argument
flip :: (a' -> b' -> c') -> b' -> a' -> c'

然后如果我们匹配类型

a = (a' -> b' -> c')
b = b'
c = a' -> c'

我们得到结果

flip flip :: b' -> (a' -> b' -> c') -> (a' -> c')

答案 1 :(得分:6)

让我们看看类型:

flip :: (a -> b -> c) -> b -> (a -> c)
flip :: (d            -> e ->  f     ) -> e ->  d            ->  f
flip flip ::                              b -> (a -> b -> c) -> (a -> c)

换句话说,flip反转其参数的前两个参数,flip的前两个参数是翻转的函数,而第二个参数是该函数。因此,当您翻转它时,它的顺序就变成了“第二个参数”,“功能”,“第一个参数”。

如果要翻转然后再翻转,您可以执行以下操作:

doubleflip x = flip (flip x)

或等效地:

doubleflip = flip . flip

(.)运算符将右侧的输出馈送到左侧。

答案 2 :(得分:4)

两次应用flip函数。如果您想两次申请flip,那么您正在寻找:

flip . flip :: (b -> a -> c) -> b -> a -> c

您在这里所做的是翻转 flip函数。因此,它将flip作为flip的函数。

我们可以将flip1 flip2的类型(我在这里使用下标来明确指出我们指的是flip)解析为:

flip1 :: (a -> b -> c) -> b -> a -> c
flip2 :: (d -> e -> f) -> e -> d -> f

由于flip2flip1的参数,因此这意味着flip2的类型与flip1的参数是相同的类型,因此意味着:

        a       -> (b ->    c    )
~ (d -> e -> f) -> (e -> (d -> f))

因此,这意味着a ~ (d -> e -> f)(类型ad -> e -> f相同),b ~ ec ~ (d -> e)。因此,函数flip1 flip2的类型是flip1的输出类型的类型,但是具有等价关系,所以这意味着:

flip1 flip2 :: b -> a -> c
flip1 flip2 :: e -> (d -> e -> f) -> (d -> e)

因此,我们基本上制作了一个函数,该函数首先获取第二个参数,然后获取该函数,然后获取第一个参数,然后使用翻转的参数调用该函数。因此,如果flip2 = flip flip的实现方式是:

flip2 :: e -> (d -> e -> f) -> (d -> e)
flip2 y f x = f x y