1

我对点运算符有点困惑。我有以下代码(用于测试):

test :: Int -> Int -> Int
test x y = f1 . f2 x y 
           where f1 n = n+1
                 f2 x' y' = x' * y'

我认为它会首先执行 (f2 xy) 然后 f1 在该结果上执行,但它会引发错误。谁能告诉我点运算符的确切定义以及等于f1 的含义。f2 xy ? (当不使用点运算符编写时)

最好的问候,Skyfe。

编辑:如果点运算符产生一个完整的新函数,我认为以下代码应该可以工作:

test :: Int -> Int -> Int
test x y = f1 . f2 x
           where f1 n = n+1
                 f2 x' y' = x' + y'

但该代码也返回错误。

4

3 回答 3

7

中缀运算符的优先级总是低于 Haskell 中的函数应用程序,所以这

f1 . f2 x

像这样解析

f1 . (f2 x)

但是,f2 x不是函数类型(好吧,如果 f2 返回一个函数,则可能是这样,但通常情况并非如此,或者在您的问题中)。由于 (.) 作用于函数,因此这不起作用。

改用 ($)

f1 $ f2 x
于 2014-11-05T00:58:39.493 回答
2

(.)一种常见的方法是结合($)

f1 . f2 $ x

这可以很容易地扩展以建立更长的“管道”:

f1 . f2 . f3 . f4 $ x

然后,如果您发现自己在其他地方需要相同的组合,则只需剪切和粘贴:

fs = f1 . f2 . f3 . f4

... fs x ... fs y
于 2014-11-05T04:53:01.673 回答
2

(我认为其他答案来得$太快了)

就像你已经知道的那样,

f1 . f2 x

被解析为

f1 . (f2 x)

(f1 . f2) x

而是做它所读的: compose f2f1然后将此组合函数应用于x. 现在

($) :: (a -> b) -> a -> b
f $ x = f x

看起来是多余的。它的主要目的是它具有最低的优先级,因此您可以避免使用括号:

foo . bar . baz $ x + y * z = (foo . bar . baz) (x + y * z)

另请参阅:Haskell:. (点)和 $(美元符号)

于 2014-11-05T06:53:57.913 回答