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

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


#1楼

$运算符用于避免括号。 之后出现的所有内容将优先于之前出现的所有内容。

例如,假设您有一行显示:

putStrLn (show (1 + 1))

如果要删除这些括号,则以下任何一行都将执行相同的操作:

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

的主要目的. 运算符不是要避免括号,而是要链接函数。 它使您可以将右侧显示的输出与左侧显示的输入绑定在一起。 通常,这也会导致括号较少,但工作方式有所不同。

回到同一个例子:

putStrLn (show (1 + 1))
  1. (1 + 1)没有输入,因此不能与一起使用. 操作员。
  2. show可以接受一个Int并返回一个String
  3. putStrLn可以使用String并返回IO ()

您可以像这样将showputStrLn

(putStrLn . show) (1 + 1)

如果您喜欢的括号太多,请使用$运算符将其删除:

putStrLn . show $ 1 + 1

#2楼

...或者您可以避免使用.$构造使用管道

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

那是在您添加了辅助函数之后:

(|>) x y = y x

#3楼

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

  • 不要使用. 如果要传递参数(调用函数),并且
  • 如果没有参数,不要使用$ (组成一个函数)

那是

show $ head [1, 2]

但永远不会:

show . head [1, 2]

#4楼

($)允许将函数链接在一起,而无需添加括号来控制评估顺序:

Prelude> head (tail "asdf")
's'Prelude> head $ tail "asdf"
's'

组合运算符(.)在不指定参数的情况下创建了一个新函数:

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"

#5楼

一个有用的应用程序让我花了一些时间从简短的说明中了解到学习haskell :

f $ x = f x

并用括号将包含infix运算符的表达式的右侧转换为前缀函数,可以编写($ 3) (4+)类似于(++", world") "hello"

为什么有人会这样做? 例如,用于功能列表。 都:

map (++", world") ["hello","goodbye"]`

和:

map ($ 3) [(4+),(3*)]

map (\\x -> x ++ ", world") ...map (\\f -> f 3) ...短。 显然,对于大多数人而言,后一种变体将更具可读性。


#6楼

了解任何事物(任何功能)的一种好方法是记住一切都是一个功能! 一般的口头禅可以帮助您,但是在像运算符这样的特定情况下,记住这一小技巧将有帮助:

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

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

只要记住要使用:t自由,并将运算符包含在()


#7楼

我认为您将在哪里使用一个简短示例. 而不是$可以帮助澄清问题。

double x = x * 2
triple x = x * 3
times6 = double . triple:i times6
times6 :: Num c => c -> c

请注意, times6是从函数组合创建的函数。


#8楼

Haskell:之间的区别. (点)和$ (美元符号)

(.)和美元符号($)什么区别? 据我了解,它们都是不需要使用括号的语法糖。

他们不是语法糖不需要使用括号-它们是功能- infixed,因此,我们可以称他们为运营商。

撰写(.)以及何时使用它。

(.)是撰写功能。 所以

result = (f . g) x

与构建将传递给g参数结果传递给f

h = \x -> f (g x)
result = h x

当您没有可用于传递给想要编写的函数的参数时,请使用(.)

右关联套用($)以及何时使用它

($)是具有低绑定优先级的右关联应用函数。 因此,它仅首先计算右边的事物。 从而,

result = f $ g x

在程序上与此相同(这很重要,因为Haskell的计算是延迟的,它将首先开始计算f ):

h = f
g_x = g x
result = h g_x

或更简而言之:

result = f (g x)

在将所有前面的函数应用于结果之前,如果要评估所有变量,请使用($)

通过阅读每个函数的源代码,我们可以看到这一点。

阅读资料

这是(.)的来源 :

-- | 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
(.) f g = \x -> f (g x)

这是($)的来源 :

-- | Application operator.  This operator is redundant, since ordinary
-- application @(f x)@ 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 $ h x  =  f (g (h x))
--
-- 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                   =  f x

结论

当您不需要立即评估该功能时,请使用组合。 也许您想将合成产生的功能传递给另一个功能。

提供所有参数以进行全面评估时,请使用application。

因此,对于我们的示例,在语义上更可取

f $ g x

当我们有x (或者说g的参数),然后执行:

f . g

当我们不这样做时。


#9楼

所有其他答案都很好。 但是,有一个重要的可用性细节涉及ghc如何处理$,ghc类型检查器允许具有较高等级/量化类型的错误。 例如,如果您查看$ id的类型,您会发现它将使用一个函数,其参数本身就是一个多态函数。 像这样的小事情在使用等效的翻转运算符时不会具有相同的灵活性。 (这实际上使我怀疑$!是否应得到相同的待遇)


#10楼

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

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

换句话说,在$的链中,除最后一个以外的所有链都可以替换为.


#11楼

另请注意, ($)专用于函数类型的标识函数 。 身份函数如下所示:

id :: a -> a
id x = x

虽然($)看起来像这样:

($) :: (a -> b) -> (a -> b)
($) = id

请注意,我有意在类型签名中添加了额外的括号。

通常可以通过添加括号来消除对($)使用(除非在节中使用了运算符)。 例如: f $ gx变为f (gx)

(.)用法通常较难替换; 他们通常需要lambda或引入显式函数参数。 例如:

f = g . h

变成

f x = (g . h) x

变成

f x = g (h x)

希望这可以帮助!


#12楼

简短而甜美的版本:

  • ($)调用函数,该函数是它的左手参数,值是它的右手参数。
  • (.)在作为右手参数的函数上组成作为左手参数的函数。

之间有什么区别。 (点)和$(美元符号)?相关推荐

  1. excel公式中的$(美元符号)的作用

    绝对引用($)与相对引用的区别 相对引用 在创建公式时,单元格或单元格区域的引用通常是相对于包含公式的单元格的相对位置.     例如,元格 B6 包含公式 =A5 :Microsoft Excel ...

  2. javascript 符号_JavaScript中的美元符号($)和下划线(_)

    javascript 符号 The dollar sign ($) and the underscore (_) characters are JavaScript identifiers, whic ...

  3. Microsoft365和普通Office之间有什么区别 如何选择?

    微软以不断改造其产品而闻名:这也适用于其举世闻名的 Office:随着 Microsoft 365 的推出,流行的办公软件现在以订阅模式提供. 尽管许多用户和企业不确定 Microsoft 365 和 ...

  4. 句法分析是什么?成分句法分析、依存句法分析又是什么?他们之间有什么区别?

    句法分析是什么?成分句法分析.依存句法分析又是什么?他们之间有什么区别? 目录

  5. 科普丨数据中心、云计算、大数据之间有什么区别和联系?

    不少人把数据中心.云计算数据中心.大数据搞混淆,觉得这三者是一样的产品,其实有显著地区别,数据中心机房是一整套复杂的设施,如今,云计算即将成为信息社会的公共资源,而数据中心则是支撑云计算服务的基础设施 ...

  6. 《中国人工智能学会通讯》——4.41 两种学习之间有什么区别?

    4.41 两种学习之间有什么区别? 来 看 一 下 剑 桥 大 学 信 息 工 程 教 授 ZoubinGhahramani 对贝叶斯规划学习(BPL)的评价,他认为 BPL 对人工智能.认知科学和机 ...

  7. 媒体查询中“屏幕”和“仅屏幕”之间有什么区别?

    本文翻译自:What is the difference between "screen" and "only screen" in media queries ...

  8. Docker映像和容器之间有什么区别?

    本文翻译自:What is the difference between a Docker image and a container? When using Docker, we start wit ...

  9. npm package.json文件中的依赖关系,devDependencies和peerDependencies之间有什么区别?

    本文翻译自:What's the difference between dependencies, devDependencies and peerDependencies in npm packag ...

最新文章

  1. JavaScript的数据类型有哪些?
  2. 关于Puppet不得不说的故事
  3. 架构师之路 — API 经济 — RESTful API
  4. 通过Spring的BeanPostProcessor的 bean的后置处理器会拦截所有bean创建过程
  5. at24c16如何划分出多个读写区_读写AT24C02,并用1602显示
  6. java/android 做题中整理的碎片小贴士(12)
  7. 设计模式之静态代理模式实战
  8. css的fill属性,css column-fill属性怎么用
  9. NOTEPAD大神是否鄙视一切IDE?
  10. 实践GoF的23种设计模式:SOLID原则(上)
  11. 只有它才能让云计算、大数据、人工智能大放异彩?它究竟有什么魔力?
  12. 『ExtJS』树 异步加载数据
  13. jsp包含html有乱码,jsp include包含html页面产生的乱码问题
  14. Windows 10 让所有程序默认为“以管理员身份运行”并且取消“确认”按钮
  15. VB6.0调用WebService
  16. python调用pandas保存excel
  17. JAVA中柱状图和折线图组合,分组折线图、柱状图实现(多条折线图、柱状图同时显示)实现方式...
  18. 如何让你画里的鱼,游进海里?
  19. Python编程笔记(第三篇)【补充】三元运算、文件处理、检测文件编码、递归、斐波那契数列、名称空间、作用域、生成器...
  20. 运动蓝牙耳机品牌推荐:2022年六大运动耳机推荐

热门文章

  1. C#打开php链接传参然后接收返回值
  2. SQL类似sleep延时语句
  3. dmidecode 硬件查看
  4. springmvc注解@
  5. App installation failed (A valid provisioning profile for this executable was not found)
  6. [CF1093G] Multidimensional Queries
  7. 这些测试细节,你注意到了吗?
  8. Xcode开发技巧——调试
  9. awksed story
  10. mysql学习笔记 ----外键.myisam和innodb的区别