Haskell中的.和$有什么区别?

7

可能是重复问题:
Haskell: .(点)和$(美元符号)之间的区别

好的,我明白这个:

f(g(x))

可以重写为:

f $ g(x)

并且也可以被重写:

f . g(x)

我不太明白的是这两个功能在哪些方面没有重叠。我从概念上理解它们并不完全重叠,但有人能为我澄清一下吗?


1
看,你实际上不能像第二个例子那样编写。试试ghci! - fuz
6
同时,对于函数调用而言,括号不是必需的(也不推荐使用)。总之,示例应为f (g x)f $ g x(f . g) x - user395760
3个回答

21
Prelude> :t ($)
($) :: (a -> b) -> a -> b
Prelude> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

$用于将一个函数应用到一个值上。.用于组合两个函数。

因此,我可以写成f $ g x,意思是“将f应用于(g的x)”或f . g $ x,意思是“将f和g的组合应用于x”。一种常见的风格是在左边堆积点,以美元符号结尾。原因是f $ g $ x的含义与f . g $ x相同,但表达式f $ g本身通常没有意义(实际上,可能是类型错误),而表达式f . g表示“f和g的组合”。


3
对于无数的 fgf $ g 是完全可行和类型正确的(考虑 (\f -> f 0) $ (\x -> x + 1)),它与 f g 完全相同。否则就是正确的。 - user395760
@delnan 我想不出一个在自身上是良好类型的 f $ g,同时也在 f $ g $ x 的上下文中是良好类型的。但这可能是想象力的失败。 - sclv
编辑以考虑您的观点。谢谢。 - sclv

14

除了已经提到的内容外,像这种情况下,你需要将$视为“函数应用粘合剂”:

map ($3) [(4+),(5-),(6*),(+4),(*5),(^6)]
--[7,2,18,7,15,729] 

(.3)(3)都不能在这个例子中使用。


3
+1 - 对讨论非常有价值 - Ramy

1
"

\"f $ g x\" 不能被重写为 \"f . g x\"。事实上,编译器甚至不会接受第二个函数,因为“(.)”的类型为“(b -> c) -> (a -> b) -> (a -> c)” 。也就是说,第二个参数必须是一个函数,但“g x”是一个值而不是函数。

"

g x将成为一个函数,用于(柯里化的)2个或更多个参数的g,例如const 0 - user395760
@delnan:是的,但我从他使用它的方式推断出g是一元的。 - keiter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接