我对点运算符有点困惑。我有以下代码(用于测试):
test :: Int -> Int -> Int
test x y = f1 . f2 x y
where f1 n = n+1
f2 x' y' = x' * y'
我认为它会首先执行(f2 x y)然后执行该结果的f1,但它会抛出错误。谁能告诉我点运算符的确切定义以及等于 f1的内容。 f2 x y ? (在没有点运算符的情况下编写)
祝你好运, Skyfe。
编辑:如果点运算符产生一个完整的新函数,我认为以下代码应该起作用:
test :: Int -> Int -> Int
test x y = f1 . f2 x
where f1 n = n+1
f2 x' y' = x' + y'
但该代码也会返回错误。
答案 0 :(得分:7)
在Haskell中,中缀运算符的优先级低于函数应用程序,所以
f1 . f2 x
像这样解析
f1 . (f2 x)
但是,f2 x
不属于类型函数(好吧,如果f2返回一个函数,可能就是这样,但一般来说,或者问题不是这样)。由于(。)作用于函数,因此无法工作。
使用($)代替
f1 $ f2 x
答案 1 :(得分:2)
一种常见方法是将(.)
与($)
合并:
f1 . f2 $ x
这可以很容易地扩展,以建立更长的“管道”:
f1 . f2 . f3 . f4 $ x
然后,如果您发现自己在其他地方需要相同的组合,则只需要剪切和粘贴:
fs = f1 . f2 . f3 . f4
... fs x ... fs y
答案 2 :(得分:2)
(我认为其他答案太快了$
)
如您所知,
f1 . f2 x
被解析为
f1 . (f2 x)
写
(f1 . f2) x
而是执行以下操作:撰写f2
和f1
,然后将此组合函数应用于x
。现在
($) :: (a -> b) -> a -> b
f $ x = f x
看起来多余了。它的主要目的是它具有最低优先级,因此您可以避免使用括号:
foo . bar . baz $ x + y * z = (foo . bar . baz) (x + y * z)
另请参阅:Haskell: difference between . (dot) and $ (dollar sign)