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

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


当前回答

其他答案都很好。但是关于ghc如何处理$有一个重要的可用性细节,ghc类型检查器允许用更高等级/量化的类型进行初始化。例如,如果你看$ id类型你会发现它将接受一个参数本身是多态函数的函数。类似这样的小事情在等效的打乱操作符中没有相同的灵活性。(这实际上让我怀疑$!是否值得同样的待遇)

其他回答

它们有不同的类型和不同的定义:

infixr 9 .
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

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

($)旨在取代普通的函数应用程序,但在不同的优先级,以帮助避免括号。(.)用于将两个函数组合在一起,生成一个新函数。

在某些情况下,它们是可以互换的,但在一般情况下并非如此。典型的例子是:

f $ g $ h $ x

==>

f . g . h $ x

换句话说,在$s链中,除了最后一个,其他的都可以被。

... 或者你可以避免。和$ structures使用管道:

third xs = xs |> tail |> tail |> head

这是在你添加了helper函数之后:

(|>) x y = y x

我的规则很简单(我也是初学者):

不要使用。如果要传递参数(调用函数),和 如果没有参数,不要使用$(合成一个函数)

这是

show $ head [1, 2]

但从来没有:

show . head [1, 2]

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

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

and

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

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

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

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

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

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