Haskell:区别。 (点)和$(美元符号)
点(.)和美元符号($)之间有什么区别? 据我了解,它们都是不需要使用括号的语法糖。 
  $运算符用于避免括号。 任何出现在它之后的东西都将优先于以前的东西。 
例如,假设您有一行代码:
 putStrLn (show (1 + 1)) 
如果你想摆脱这些括号,下面的任何一行也会做同样的事情:
 putStrLn (show $ 1 + 1) putStrLn $ show (1 + 1) putStrLn $ show $ 1 + 1 
 的主要目的. 运算符不是为了避免括号,而是为了链接函数。 它可以让你把任何出现在右边的输出与出现在左边的任何input连接起来。 这通常也会减less括号,但工作方式不同。 
回到相同的例子:
 putStrLn (show (1 + 1)) 
-   (1 + 1)没有input,因此不能用于.运营商。
-   show可以接受一个Int并返回一个String。
-   putStrLn可以接受一个String并返回一个IO ()。
 你可以链show putStrLn像这样: 
 (putStrLn . show) (1 + 1) 
 如果这是你所喜欢的太多括号,用$运算符来消除它们: 
 putStrLn . show $ 1 + 1 
它们有不同的types和不同的定义:
 infixr 9 . (.) :: (b -> c) -> (a -> b) -> (a -> c) (f . g) x = f (gx) infixr 0 $ ($) :: (a -> b) -> a -> b f $ x = fx 
  ($)是为了替代正常的函数应用,但以不同的优先级来避免括号。  (.)是为了组合两个函数一起做出一个新的函数。 
在某些情况下,它们是可以互换的,但是这通常是不正确的。 典型的例子是:
 f $ g $ h $ x 
==>
 f . g . h $ x 
 换句话说,在一连串的$ s中,除了最后一个之外,所有的都可以被replace. 
 还要注意($)是专门用于函数types的标识函数 。 身份函数如下所示: 
 id :: a -> a id x = x 
  ($)看起来像这样: 
 ($) :: (a -> b) -> (a -> b) ($) = id 
请注意,我有意在types签名中添加了额外的括号。
  ($)使用通常可以通过添加括号来消除(除非操作符在一个段中使用)。 例如: f $ gx变成f (gx) 。 
  (.)用法往往稍微难以取代; 他们通常需要一个lambda或引入一个明确的函数参数。 例如: 
 f = g . h 
变
 fx = (g . h) x 
变
 fx = g (hx) 
希望这可以帮助!
  ($)允许将函数链接在一起而不添加括号来控制评估顺序: 
 Prelude> head (tail "asdf") 's' Prelude> head $ tail "asdf" 's' 
 组合运算符(.)创build一个新的函数,但不指定参数: 
 Prelude> let second x = head $ tail x Prelude> second "asdf" 's' Prelude> let second = head . tail Prelude> second "asdf" 's' 
上面的例子可以说明性的,但并没有真正显示使用组合的方便。 这是另一个比喻:
 Prelude> let third x = head $ tail $ tail x Prelude> map third ["asdf", "qwer", "1234"] "de3" 
如果我们只使用第三次,我们可以避免使用lambda命名:
 Prelude> map (\x -> head $ tail $ tail x) ["asdf", "qwer", "1234"] "de3" 
最后,作文让我们避免了lambda:
 Prelude> map (head . tail . tail) ["asdf", "qwer", "1234"] "de3" 
短而甜的版本:
-   ($)调用作为它的右手参数的左值参数的函数。
-   (.)构成函数的左手参数,即右手参数。
一个有用的应用程序,花了我一些时间,从简短的描述中找出你学习haskell :从以下版本开始:
 f $ x = fx 
 并将包含中缀运算符的expression式的右侧括起来,将其转换为前缀函数,可以类似于(++", world") "hello"来写($ 3) (4+) 。 
为什么有人会这样做? 例如,对于function列表。 都:
 map (++", world") ["hello","goodbye"]` 
和:
 map ($ 3) [(4+),(3*)] 
 比map (\x -> x ++ ", world") ...或map (\f -> f 3) ...短。 显然,后者的变体对于大多数人来说更易读。 
  …或者你可以避免的. 和$使用stream水线结构 : 
 third xs = xs |> tail |> tail |> head 
这是在添加辅助函数之后:
 (|>) xy = yx 
了解更多关于任何东西(任何function)的好方法是记住一切都是一个function! 这个通用的口头禅可以帮上忙,但是在像操作员这样的特殊情况下,记住这个小窍门会有帮助:
 :t (.) (.) :: (b -> c) -> (a -> b) -> a -> c 
和
 :t ($) ($) :: (a -> b) -> a -> b 
 只要记住要使用:t ,然后在()包装你的运算符! 
我的规则很简单(我也是初学者):
-  不要使用.如果你想传递参数(调用函数),并且
-  如果还没有参数,请不要使用$(组成一个函数)
那是
 show $ head [1, 2] 
但从来没有:
 show . head [1, 2] 
 我想一个你可以使用的简单例子. 而不是$将有助于澄清事情。 
 double x = x * 2 triple x = x * 3 times6 = double . triple :i times6 times6 :: Num c => c -> c 
 请注意, times6是从函数组合创build的函数。 
Haskell:区别
.(点)和$(美元符号)点
(.)和美元符号($)之间有什么区别? 据我所知,它们都是不需要使用括号的语法糖。
由于不需要使用括号,它们不是句法糖 – 它们是function, – 是固定的,因此我们可以称它们为操作符。
  (.)是组合function。 所以 
 result = (f . g) x 
 与构build一个将传递给g参数的结果传递给f 。 
 h = \x -> f (gx) result = hx 
  ($)是具有低绑定优先级的右联合应用函数。 所以它只是首先计算它的权利。 从而, 
 result = f $ gx 
 和程序上的一样(这很重要,因为Haskell是懒惰的评估,它会先开始评估f ): 
 h = f g_x = gx result = h g_x 
或者更简洁:
 result = f (gx) 
我们可以通过阅读每个函数的源代码来看到这一点。
阅读来源
 这是(.)的来源 : 
 -- | Function composition. {-# INLINE (.) #-} -- Make sure it has TWO args only on the left, so that it inlines -- when applied to two functions, even if there is no final argument (.) :: (b -> c) -> (a -> b) -> a -> c (.) fg = \x -> f (gx) 
 这是($)的来源 : 
 -- | Application operator. This operator is redundant, since ordinary -- application @(fx)@ means the same as @(f '$' x)@. However, '$' has -- low, right-associative binding precedence, so it sometimes allows -- parentheses to be omitted; for example: -- -- > f $ g $ hx = f (g (hx)) -- -- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@, -- or @'Data.List.zipWith' ('$') fs xs@. {-# INLINE ($) #-} ($) :: (a -> b) -> a -> b f $ x = fx 
何时使用:
当你不需要立即评估function时使用组合。 也许你想把构成的function传递给另一个function。
在提供所有参数以进行全面评估时使用应用程序。
所以对于我们的例子来说,这样做在语义上是可取的
 f $ gx 
 当我们有x (或者说, g的参数),并且: 
 f . g 
当我们不。