Haskell :: 符号 $ 的使用

Haskell :: The use of symbol $

这是我的代码:

    data = [1,2,3,4,5,6,7,8,9,10]
    cak' [] = []
    cak' (x:xs) =
        if x >= 2 then
            cak' (x - 2) : cak' (xs)
        else
            x : cak' (xs)
    run = cak' data

我把cak' (x - 2) : cak' (xs)改成cak' $ x - 2 : cak' (xs)才行。为什么会产生这样的影响?

这是一个运算符优先级的问题:

  • cak' (x - 2) : cak' (xs) 等同于 (cak' (x - 2)) : (cak' (xs))

  • cak' $ (x - 2) : cak' (xs) 等同于 cak' ( (x - 2) : cak' (xs) )

您可以将 $ 读作 "use everything after the $ as a single argument for the function before the $"。它有点像一组您不必关闭的括号。

函数应用(比如f x,请不要写成f (x) 顺便说一句)总是比任何中缀运算符(比如:,尤其是[=14]绑定得更紧密=]).所以 cak' (x - 2) : cak' xs 实际上被解析为 (cak' (x - 2)) : cak' xs,它不进行类型检查(因为 x - 2 不是列表)。

另一方面,$ 绑定 比所有其他标准中缀运算符弱 ,因为

Prelude> :i $
($) :: (a -> b) -> a -> b   -- Defined in ‘GHC.Base’
infixr 0 $
Prelude> :i :
...
infixr 5 :

...即: 具有固定性 5 但 $ 仅固定性 0。因此,cak' $ (x - 2) : cak' xs 被解析为(可能)正确的东西,即 cak' ((x - 2) : cak' xs).