简体   繁体   English

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

[英]Haskell: applying flip twice (type of flip flip)

I am learning Haskell along some basic functions. 我正在学习Haskell的一些基本功能。 I was doing some exercises with Flip, which takes a function of two arguments and evaluates the result flipping the order of the arguments. 我正在用Flip做一些练习,它接受两个参数的函数并评估翻转参数顺序的结果。 Consider the function flip flip , I would have thought, following the definition of flip, that it flipped the arguments twice, evaluating the original function with the parameters in the original order. 考虑到翻转功能,我认为,按照翻转的定义,它会翻转参数两次,用原始顺序中的参数评估原始函数。 When I checked this assumption with ghci checking the function type, it yielded: 当我用ghci检查函数类型检查这个假设时,它产生了:

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

I don't understand why this is the function type of flip flip. 我不明白为什么这是翻盖的功能类型。 It takes parameter b and parameter (a -> b -> c) and yields a function a -> c. 它需要参数b和参数(a - > b - > c)并产生一个函数a - > c。 Why is this the case ? 为什么会这样? I would really appreciate an explanation since I am at lost with this. 我真的很感激解释,因为我迷失了这个。 Thanks in advance 提前致谢

Flipping twice would be \\f -> flip (flip f) , or flip . flip 翻转两次将是\\f -> flip (flip f)flip . flip flip . flip . flip . flip This would indeed have the type (a -> b -> c) -> (a -> b -> c) . 这确实有类型(a -> b -> c) -> (a -> b -> c)

What you are doing here instead is applying flip on the flip function, ie flipping flip 's argument order. 你在这里所做的不是在flip函数上应用flip ,即翻转flip的参数顺序。 So if we start with 所以,如果我们开始

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

then if we match the types 那么如果我们匹配类型

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

we get the result 我们得到了结果

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

Let's look at the types: 我们来看看类型:

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

In other words, flip reverses the first two arguments of its argument, and the first two arguments of flip are the function to flip and the second argument to that function. 换句话说, flip反转其参数的前两个参数,而flip的前两个参数是flip的函数和该函数的第二个参数。 So instead of taking arguments in the order 'function', 'second argument', 'first argument', the order becomes 'second argument', 'function', 'first argument' when you flip it. 因此,不是按照'function','second argument','first argument'的顺序接受参数,而是当你翻转它时,顺序变为'second argument','function','first argument'。

If you want to flip, and then flip back, you do something like this: 如果你想翻转,然后翻转,你会做这样的事情:

doubleflip x = flip (flip x)

Or equivalently: 或等效地:

doubleflip = flip . flip

The (.) operator feeds the output of the right-hand side into the left-hand side. (.)运算符将右侧的输出馈送到左侧。

You do not apply the flip function twice. 应用flip功能两次。 If you want to apply flip twice, you are looking for: 如果你想要flip两次,你正在寻找:

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

What you here do is flipping the flip function. 你在这里做的是翻转 flip功能。 So it takes flip as the function to flip . 所以它需要flip才能flip

We can resolve the type of flip 1 flip 2 (I here use subscripts to make it clear to which flip we are referring) as: 我们可以解决flip 1 flip 2的类型(我这里使用下标来明确我们所指的flip ):

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

Since flip 2 is the parameter of flip 1 , so that means that the type of flip 2 is the same type of the parameter of flip 1 , so that means that: 由于flip 2flip 1的参数,因此这意味着flip 2的类型与flip 1的参数类型相同,因此这意味着:

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

Hence that means that a ~ (d -> e -> f) (the type a is the same as d -> e -> f ), b ~ e and c ~ (d -> e) . 因此,这意味着a ~ (d -> e -> f) (类型ad -> e -> f ), b ~ ec ~ (d -> e) So the type of the function flip 1 flip 2 is the type of the output type of flip 1 , but with the equivalences, so that means that: 所以函数flip 1 flip 2的类型是flip 1的输出类型的类型,但是具有等价,所以这意味着:

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

We basically thus made a function that first takes the second parameter, then takes the function, and then the first parameter, and then calls that function with the flipped parameters. 我们基本上创建了一个函数,首先获取第二个参数,然后获取函数,然后是第一个参数,然后使用翻转的参数调用该函数。 So if flip2 = flip flip , it is implemented like: 因此,如果flip2 = flip flip ,它实现如下:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM