11

我在理解函数应用程序如何在curk in haskell中工作时遇到问题。 如果我有以下功能:Haskell美元运算符应用程序

($) :: (a -> b) -> a -> b 

据我所知,部分地应用此功能,我需要提供(a -> b)功能($的第一个参数)。

为什么然后有可能先应用一个值(即反向参数)?

($ 0) :: Num a => (a -> b) -> b 

我在这里错过了什么?

回答

13

($)是运营商。在Haskell中,任何操作员可以写成左部分(如(x $))或右部分(如($ x)):

(x $) = (\y -> x $ y) = ($) x 
($ x) = (\y -> y $ x) = flip ($) x 

注意唯一的例外是(-),为了方便写负数:要简洁地写(\y -> y - x)

\x -> (x-) :: Num a => a -> a -> a -- equivalent to \x -> (-) x 
\x -> (-x) :: Num a => a -> a  -- equivalent to \x -> negate x 

在情况下,你可以使用subtract

\x -> subtract x :: Num a => a -> a -> a -- equivalent to \x -> flip (-) x 
+0

谢谢,这解释了它为什么这样工作。这些定义是语言特性还是可以在源代码中找到它们? – Rumca

+2

@Rumca没有真正的来源,(x $)和($ x)是章节,并且可以在[2010 haskell报告]中找到它们的描述(http://www.haskell.org/onlinereport/haskell2010/ )[部分](http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-300003.5)。 – Davorak

+0

该语言在[Haskell 2010报告](http://www.haskell.org/onlinereport/haskell2010/)中描述。 –

4

($ 0)(\x -> x $ 0)(\x -> ($) x 0)

如果($) :: (a -> b) -> a -> b),我们采用第二个参数一样(\x -> ($) x 0)我们:: Num a => (a -> b) -> b

2

您正混淆操作符的中缀表示法和函数。

> :t (($) (+1)) 
(($) (+1)) :: Num b => b -> b 

下面是一些形式的表达式与$,为了更好地理解:

一个$ B =>($)AB

($ B)=>翻转($)b =>(\ BA - >($)AB)b => \一个 - >($)AB

(一个$)=>($)A => \乙 - >($)AB

+0

-1即使有人坚信这个问题是关于什么以及理由是什么,我发现这个答案是不可理解的。那些不熟悉Haskell的人应该如何理解这一点?没有解释操作员和功能之间的区别。 '$ b => flip($)b => \ a - >($)a b'甚至不是有效的语法。 (编辑:好吧,如果我有更多的代表,它会是-1。) –

1

还要注意,在Haskell语法中,字母数字名称与标点符号名称不同。

默认情况下,字母数字函数foo1 a b是前缀,如果添加反引号,则会成为中缀:a `foo` b

标点符号命名的功能类似$<*>默认情况下缀,如果您添加括号($)(<*>)成为前缀。这只是熟悉拉丁字母的程序员的语法糖;它是字母数字名称和标点符号名称之间的任意但有用的区别。

这两种函数都只是函数,它们没有C++或Java中“操作符”的特殊语义规则。它只是围绕前缀/中缀和反引号/括号的语法规则,它们在标点名称函数和字母数字命名函数之间不同。