翻转功能如何工作?

ers*_*an9 32 haskell

Haskell新手在这里.我正在通过了解你是一个haskell,并且遇到了翻转功能的这个定义.

flip' :: (a -> b -> c) -> (b -> a -> c)  
flip' f = g  
    where g x y = f y x
Run Code Online (Sandbox Code Playgroud)

我没有得到的是,x和y来自哪里?签名告诉我,这flip'是一个函数,它接受一个函数(带有两个参数),并返回一个函数(同样,带有两个参数).

如果我理解这一点,当我写一个类似的函数时

foo :: (a -> b) -> a -> b
foo f x = f x   -- applies the function f on x
Run Code Online (Sandbox Code Playgroud)

但是,在这种情况下,我明确地传递参数[ie x],所以我能够在函数体中访问它.那么为什么flip'函数可以访问参数x和y呢?

Dav*_*rak 36

前奏,这是在包在hackage.haskell.org,被包括在每一个Haskell的文件的隐式进口是其中翻盖功能被发现.在右侧,您可以单击"源"并查看翻转源代码.

flip         :: (a -> b -> c) -> b -> a -> c
flip f x y   =  f y x
Run Code Online (Sandbox Code Playgroud)

where子句允许本地定义,x=10y="bla".您还可以使用与顶级语法相同的语法在本地定义函数.add x y = x + y

在以下等效配方中,我进行了替换 g = f y x

flip         :: (a -> b -> c) -> b -> a -> c
flip f x y   =  g
  where
    g = f y x
Run Code Online (Sandbox Code Playgroud)

现在g没有参数.但是,如果我们定义了g,g a b = f b a那么我们会:

flip         :: (a -> b -> c) -> b -> a -> c
flip f x y   =  g x y
  where
    g a b = f b a
Run Code Online (Sandbox Code Playgroud)

不,我们可以做一点代数取消(如果你认为它像数学类的代数那么你会非常安全).专注于:

flip f x y   =  g x y
Run Code Online (Sandbox Code Playgroud)

取消每边的y:

flip f x   =  g x
Run Code Online (Sandbox Code Playgroud)

现在取消x:

flip f   =  g
Run Code Online (Sandbox Code Playgroud)

现在把它放回到完整的表达中:

flip     :: (a -> b -> c) -> b -> a -> c
flip f   =  g
  where
    g a b = f b a
Run Code Online (Sandbox Code Playgroud)

作为最后一步的化妆品,我们可以做出替换a,以xby向下恢复功能参数名:

flip     :: (a -> b -> c) -> b -> a -> c
flip f   =  g
  where
    g x y = f y x
Run Code Online (Sandbox Code Playgroud)

正如你所看到的那样,翻转的定义是有点圆的,我们在前奏中开始的是简单的,我喜欢的定义.希望这有助于解释如何where工作以及如何对Haskell代码进行一些代数操作.


Ben*_*Ben 15

flip'不访问xy.它接收一个参数f,并计算表达式g.没有xy在视线内.

然而,g它本身就是一个函数,用where子句中的辅助方程定义flip'.

您可以g x y = f y x完全阅读,就像它是一个顶级等式一样flip'.这g是两个参数的函数,xy.它g可以访问,xy不是flip'.这些参数的值在g应用之前不存在,直到flip'返回函数之后才会存在g(如果有的话).

关于gwhere子句中定义的特殊之处在于flip'它可以访问参数flip',这是如何g定义的f.

所以当flip'调用它时会收到一个函数f.对于每个特定的调用flip',它构造一个新函数g.g会收到两个参数,x并且y,当它被调用时,但尚未发生.flip'然后只返回g结果.