目前我正在通过《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
3条答案
按热度按时间ogq8wdun1#
我认为作者头脑中的论证过于简略,以至于根本没有意义,但我对推理的猜测是这样的:我们从第一个定义开始:
现在我们看到这是一个curried的东西,我们使用所有关于
(->)
和junk的结合性的讨论来写同样的东西,但是f
有两个额外的参数,像这样:现在我们有了他所说的双向方程:
g x y = f y x
,反之亦然。我们可以使用下面的等式重写flip
的主体,如下所示:由于定义的主体不再提及
g
,我们可以将其删除。现在,我们差不多做到了。在最后的定义中,作者把所有地方的名字
x
和y
都换了。我不知道他们为什么要这样做,但这是一个法律的的举动,你可以在等式推理中这样做,所以没有问题。这样做就给了我们他们最终的等式:vddsk6oq2#
flip
接受一个函数,并返回该函数的翻转版本。定义flip'
的一种方法是在定义本身中包含应用程序,因为也就是说,
flip' f
是将f
以相反顺序应用于其自身参数的函数。第二个定义只是先给匿名函数
\y -> \x -> f x y
一个名字,然后用这个名字作为flip' f x y
的定义。也就是说,
flip' f
是某个函数g
,其中g
被定义为以相反的顺序将f
应用于g
的自变量。定义
g x y = f y x
和g y x = f x y
等价于alpha conversion。在这两种情况下,f
在g
的定义中是自由变量;g
是flip'
的f
参数上的闭包。k4aesqcs3#
如果您正在这里寻找什么翻转做: