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=10
或y="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
,以x
和b
以y
向下恢复功能参数名:
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'
不访问x
和y
.它接收一个参数f
,并计算表达式g
.没有x
或y
在视线内.
然而,g
它本身就是一个函数,用where
子句中的辅助方程定义flip'
.
您可以g x y = f y x
完全阅读,就像它是一个顶级等式一样flip'
.这g
是两个参数的函数,x
和y
.它g
可以访问,x
而y
不是flip'
.这些参数的值在g
应用之前不存在,直到flip'
返回函数之后才会存在g
(如果有的话).
关于g
在where
子句中定义的特殊之处在于flip'
它可以访问参数flip'
,这是如何g
定义的f
.
所以当flip'
调用它时会收到一个函数f
.对于每个特定的调用flip'
,它构造一个新函数g
.g
会收到两个参数,x
并且y
,当它被调用时,但尚未发生.flip'
然后只返回g
结果.