gpt4 book ai didi

Haskell:获取不带括号的前缀运算符

转载 作者:行者123 更新时间:2023-12-03 14:51:28 25 4
gpt4 key购买 nike

前缀运算符很好的一个重要原因是它们可以避免使用括号,以便 + - 10 1 2明确表示 (10 - 1) + 2 .如果括号被删除,中缀表达式会变得模棱两可,你可以通过某些优先规则来消除它,但这很困惑,等等。

我想让 Haskell 使用前缀操作,但我见过的唯一方法是通过去掉括号来交换 yield 。

Prelude> (-) 10 1 

使用两个括号。

当您尝试组合函数时,情况会变得更糟,因为
Prelude> (+) (-) 10 1 2 

产生一个错误,我相信因为它试图将减号操作输入到加号操作中,而不是先评估减号然后再输入 - 所以现在你需要更多的括号!

有没有办法让 Haskell 智能地评估前缀符号?我想如果我制作这样的功能
Prelude> let p x y = x+y
Prelude> let m x y = x-y

我会在更少的括号中恢复最初的 yield ,但功能组合仍然是一个问题。如果有一个聪明的方法可以加入 $使其行为至少接近我想要的方式的符号,我没有看到它。如果有完全不同的策略可用,我会很高兴听到它。

我尝试复制此处接受的答案:

Haskell: get rid of parentheses in liftM2

但在 Prelude 控制台和 Haskell 脚本中,导入命令都不起作用。此外,这是比我能够理解的更高级的 Haskell,所以我希望在我做繁重的工作之前可能有一些其他更简单的解决方案来调查它在做什么。

最佳答案

It gets even worse when you try to compose functions because

Prelude> (+) (-) 10 1 2 

yields an error, I believe because it's trying to feed the minus operation into the plus operations rather than first evaluating the minus and then feeding--so now you need even more parens!



在这里,您准确地提出了阻碍在 Haskell 中获得所需内容的关键问题。

您正在谈论的前缀表示法对于基本算术运算是明确的(更一般地说,对于任何静态已知数量的函数集)。但是你要知道 +-每个接受 + - 10 1 2 的 2 个参数明确地解析为 +(-(10, 1), 2) (我有明确的参数列表来表示每个调用)。

但是忽略了 +的具体含义和 - ,第一个函数以第二个函数为参数是完全合理的解释!对于 Haskell 而不是算术,我们需要支持像 map 这样的高阶函数。 .你会想要 not not x必须变成 not(not(x)) , 但是 map not x必须变成 map(not, x) .

如果我有 f g x ?那应该如何工作?我需要知道什么 fg一定要这样我才能知道它是否像 not not x 这样的情况或类似 map not x 的案例,只是想知道如何解析调用结构?即使假设我有所有代码可供检查,如果我不知道任何表达式的调用结构是什么,我应该如何弄清楚绑定(bind)了什么?

你最终需要发明像 map (not) x 这样的消歧语法。 , 包装 not在括号中禁用它像 arity-1 函数一样的能力(很像 Haskell 的实际语法允许您将运算符包装在括号中以禁用它们像中缀运算符一样的能力)。或者使用所有 Haskell 函数都是 arity-1 的事实,但是你必须写 (map not) x并且您的算术示例必须看起来像 (+ ((- 10) 1)) 2 .回到括号!

事实是您提出的前缀符号 不是 明确的。 Haskell 的普通函数语法(无运算符) ;规则是您总是解释一系列术语,如 foo bar baz qux etc((((foo) bar) baz) qux) etc (其中 foo、bar 等中的每一个都可以是标识符或括号中的子项)。您使用括号不是为了消除该规则的歧义,而是对术语进行分组以施加与该硬规则给您不同的调用结构。

中缀运算符确实使该规则复杂化,并且在不了解所涉及运算符的情况下它们是模棱两可的(它们的优先级和关联性,与 arity 不同,它与 名称 相关联,而不是实际引用的值)。添加了这些复杂性以帮助使代码更易于理解;特别是对于大多数程序员已经熟悉的算术约定( + 的优先级低于 * 等)。

如果您不喜欢必须记住运算符的优先级和关联性的额外负担(不是不合理的位置),您可以自由使用不需要优先级规则的明确表示法,但它必须是 Haskell 的 前缀表示法,而不是波兰语前缀表示法。无论您使用什么语法约定,在任何语言中,您都会 总是 必须使用括号之类的东西来指示您需要的调用结构与标准约定所指示的不同的分组。所以:
(+) ((-) 10 1) 2

或者:
plus (minus 10 1) 2

如果您定义非运算符函数名称。

关于Haskell:获取不带括号的前缀运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42518003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com