haskell - 运算符(例如 +)的行为更像是 curried 函数还是带有一对元组类型参数的函数?
问题描述
如何找出运算符“+”的类型?说运算符+
不是函数。
诸如此类的运算符的+
行为更像是,
- 一个柯里化函数,或者
- 一个函数,其参数具有一对元组类型?
按运营商的说法#
,我的意思#
不是(#)
。(#)
是一个柯里化函数,如果#
表现得像一个柯里化函数,我想没有必要拥有(#)
,不是吗?
谢谢。
解决方案
根据 Haskell 2010 年的报告:
运算符符号 [不以冒号开头] 是一个普通标识符。1
因此,+
是一个标识符。标识符可以识别不同的事物,在 的情况下+
,它从类型类中识别出一个函数Num
。该函数的行为类似于任何其他 Haskell 函数,除了涉及所述函数的表达式的不同解析规则。
具体来说,这在3.2中有所描述。
运算符是一个函数,可以使用中缀语法(第 3.4 节)应用,或使用节部分应用(第 3.5 节)。
为了确定什么构成运算符,我们可以进一步阅读:
运算符要么是运算符符号,例如
+
or$$
,要么是包含在重音符号(反引号)中的普通标识符,例如`op`
2。
所以,总结一下:
+
是一个标识符。它是一个操作符符号,因为它不以冒号开头,并且只使用非字母数字字符。当在表达式中使用时(作为表达式的一部分进行解析),我们将其视为operator,这反过来意味着它是一个函数。
为了具体回答您的问题,您所说的一切都只涉及语法。对()
in 表达式的需求仅仅是启用前缀应用程序。在所有其他不需要这种消歧的情况下(例如:type
),以这种方式实现可能更容易,因为您可以只期望普通标识符并将负担推给用户。
1对于它的价值,我认为该报告在这里实际上具有误导性。这个特定的陈述似乎与其他部分相冲突,关键是:
对偶,运算符符号可以通过将其括在括号中转换为普通标识符。
我的理解是,在第一个引号中,“普通”的上下文意味着它不是类型构造函数运算符,而是值类别运算符,因此“值类别”表示“普通”。在其他引号中,“普通”用于不是操作符标识符的标识符;区别显然是应用程序。这将证实将运算符标识符包含在括号中的事实,我们将其转换为普通标识符以用于前缀 application。呼,至少我没有写那份报告;)
2我想在这里指出一件额外的事情。既不`(+)`
也不(`add`)
实际解析。第二个是可以理解的,因为报告明确指出,用括号括起来仅适用于操作符标识符,可以看出`add`
,虽然是操作符,但不是像 . 那样的操作符标识符+
。
第一种情况对我来说实际上有点棘手。由于我们可以通过将普通标识符括在反引号中来获得运算符,(+)
因此并不完全像add
. 我测试过的语言,或者至少是 GHC 解析器,似乎区分了“普通普通”标识符和通过用括号括起来运算符符号获得的普通标识符。这是否实际上与规范相矛盾,或者是另一种混合命名的情况,目前我还不知道。
推荐阅读
- python-3.x - 为什么只打印最后一个字母
- mpxj - 如何使用 MPXJ 库知道确切的 MS Project 版本
- swift - Braintree 支付集成:使用客户端授权令牌化密钥
- c# - 图表项目必须能够区分它的两个不同副本的哪些属性?
- python - 在某个时间范围内从 google pub/sub 接收消息
- mysql - 参数化 SQL 查询
- javascript - 无法阻止输入字段自动填充
- xamarin.forms - 应用程序无法在 iPhone 上部署显示“ApplicationVerificationFailed:应用程序缺少应用程序标识符权利。”
- html - 输入类型号限制长度并允许 + 符号
- autodesk-forge - 是否可以使用 Design Automation API 从 Revit 模型导出 3d 视图?