Haskell中flip函数的定义

nkoocmlb  于 2022-11-14  发布在  其他
关注(0)|答案(3)|浏览(244)

目前我正在通过《Learn You a Haskell》这本书学习Haskell,并且我正在试图理解flip函数在chapter 5中的实现。问题是作者声明如果g x y = f y x是有效的,那么f y x = g x y也必须是真的。但是这种颠倒是如何以及为什么会影响这两个函数的定义呢?
我知道currying是如何工作的,我也知道->运算符在默认情况下是右关联的,所以类型声明实际上是相同的。我也理解了彼此不同的函数,但不知道g x y = f y x的反转与此有什么关系。
第一翻转功能

flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = g
    where g x y = f y x

第二翻转功能

flip' :: (a -> b -> c) -> b -> a -> c
flip' f y x = f x y
ogq8wdun

ogq8wdun1#

我认为作者头脑中的论证过于简略,以至于根本没有意义,但我对推理的猜测是这样的:我们从第一个定义开始:

flip f = g where g x y = f y x

现在我们看到这是一个curried的东西,我们使用所有关于(->)和junk的结合性的讨论来写同样的东西,但是f有两个额外的参数,像这样:

flip f x y = g x y where g x y = f y x

现在我们有了他所说的双向方程:g x y = f y x,反之亦然。我们可以使用下面的等式重写flip的主体,如下所示:

flip f x y = f y x where g x y = f y x

由于定义的主体不再提及g,我们可以将其删除。

flip f x y = f y x

现在,我们差不多做到了。在最后的定义中,作者把所有地方的名字xy都换了。我不知道他们为什么要这样做,但这是一个法律的的举动,你可以在等式推理中这样做,所以没有问题。这样做就给了我们他们最终的等式:

flip f y x = f x y
vddsk6oq

vddsk6oq2#

flip接受一个函数,并返回该函数的翻转版本。定义flip'的一种方法是在定义本身中包含应用程序,因为

flip' f y x = f x y  ===> flip' f y = \x -> f x y
                     ===> flip' f = \y -> \x -> f x y

也就是说,flip' f是将f以相反顺序应用于其自身参数的函数。
第二个定义只是先给匿名函数\y -> \x -> f x y一个名字,然后用这个名字作为flip' f x y的定义。

===> flip' f = g where g = \y -> \x -> f x y
                     ===> flip' f = g where g y = \x -> f x y
                     ===> flip' f = g where g y x = f x y

也就是说,flip' f是某个函数g,其中g被定义为以相反的顺序将f应用于g的自变量。
定义g x y = f y xg y x = f x y等价于alpha conversion。在这两种情况下,fg的定义中是自由变量; gflip'f参数上的闭包。

k4aesqcs

k4aesqcs3#

如果您正在这里寻找什么翻转做:

Prelude> pow x y = x ^ y
Prelude> pow 2 3
8
Prelude> flip pow 2 3
9

相关问题