点(.)和美元符号($)的区别是什么?

根据我的理解,它们都是不需要使用括号的语法糖。


当前回答

关于$最重要的部分是它具有最低的操作符优先级。

如果你输入info,你会看到:

λ> :info ($)
($) :: (a -> b) -> a -> b
    -- Defined in ‘GHC.Base’
infixr 0 $

这告诉我们它是一个具有右结合性的中缀运算符,具有最低的可能优先级。普通函数应用程序是左关联的,具有最高优先级(10)。$正好相反。

所以我们在普通函数application或using()不起作用的地方使用它。

例如,这是可行的:

λ> head . sort $ "example"
λ> e

但这不是:

λ> head . sort "example"

因为。(sort "example")的优先级比sort低,类型是[Char]

λ> :type (sort "example")
(sort "example") :: [Char]

但是。需要两个函数,没有一个简单的方法来实现因为排序和操作的顺序。

其他回答

$操作符用于避免括号。在它之后出现的任何东西都会优先于在它之前出现的任何东西。

例如,假设你有一行是这样写的:

putStrLn (show (1 + 1))

如果你想去掉这些括号,下面的任何一行也会做同样的事情:

putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1

的主要目的。运算符不是为了避免圆括号,而是为了链函数。它允许您将右边出现的任何输出与左边出现的任何输入联系起来。这通常也会导致括号更少,但工作方式不同。

回到同样的例子:

putStrLn (show (1 + 1))

(1 + 1)没有输入,因此不能与。操作符。 show可以接受Int类型并返回String类型。 putStrLn可以接受String并返回IO()。

你可以这样链式显示strln:

(putStrLn . show) (1 + 1)

如果括号太多,可以用$操作符去掉:

putStrLn . show $ 1 + 1

简短而甜蜜的版本:

($)调用作为其左实参的函数对作为其右实参的值进行调用。 (.)将作为其左参数的函数组合到作为其右参数的函数上。

关于$最重要的部分是它具有最低的操作符优先级。

如果你输入info,你会看到:

λ> :info ($)
($) :: (a -> b) -> a -> b
    -- Defined in ‘GHC.Base’
infixr 0 $

这告诉我们它是一个具有右结合性的中缀运算符,具有最低的可能优先级。普通函数应用程序是左关联的,具有最高优先级(10)。$正好相反。

所以我们在普通函数application或using()不起作用的地方使用它。

例如,这是可行的:

λ> head . sort $ "example"
λ> e

但这不是:

λ> head . sort "example"

因为。(sort "example")的优先级比sort低,类型是[Char]

λ> :type (sort "example")
(sort "example") :: [Char]

但是。需要两个函数,没有一个简单的方法来实现因为排序和操作的顺序。

我想举个简短的例子。而不是$将有助于澄清事情。

double x = x * 2
triple x = x * 3
times6 = double . triple

:i times6
times6 :: Num c => c -> c

请注意,times6是一个由函数组合创建的函数。

学习任何东西(任何函数)的一个好方法是记住所有东西都是函数!一般的咒语是有帮助的,但在特定的情况下,比如运算符,它有助于记住这个小技巧:

:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

and

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

只需记住大量使用:t,并将操作符包装在()中!