`Operator` 词的定义是什么?

What is the `Operator` word definition?

我学Haskell。 Haskell中的operator字是什么定义?我找不到明确的定义。

我觉得是差不多(我自己的理解):

Operator is a function with the name, containing the ascSymbol symbols only, not starting with the : symbol and has two parameters only.

自 Haskell 2010 年 ascSymbol 组包含:

! # $ % & * + . / < = > ? @ \ ˆ | - ˜ :

但是我不确定我说的对不对... 比如这个运算符在我看来:

(!#$%&*+./<=>?@\^|-~:) :: Int -> Int -> Int
a !#$%&*+./<=>?@\^|-~: b = a * b

输出:

λ: 10 !#$%&*+./<=>?@\^|-~: 20
200
λ: (!#$%&*+./<=>?@\^|-~:) 40 20
800

但是这个(?):

(!#$%&*+./<=>?@\^|-~:) :: Int -> Int
(!#$%&*+./<=>?@\^|-~:) a = a * a

输出:

λ: (!#$%&*+./<=>?@\^|-~:) 5
25

或者这个(?):

(!#$%&*+./<=>?@\^|-~:) :: Int -> Int -> Int -> Int
(!#$%&*+./<=>?@\^|-~:) a b c = a + b + c

输出:

λ: (!#$%&*+./<=>?@\^|-~:) 3 5 6
14
λ: (3 !#$%&*+./<=>?@\^|-~: 5) 6
14

第二个和第三个变体也是运算符吗?

根据Haskell Report

an operator symbol can be converted to an ordinary identifier by enclosing it in parentheses.

所以这个(!#$%&*+./<=>?@\^|-~:)是一个普通的标识符。

好吧,因为有太多的困惑,我决定再给出一个答案。

引用自 Haskell 2010 年报告:

Haskell provides special syntax to support infix notation. An operator is a function that can be applied using infix syntax (Section 3.4), or partially applied using a section (Section 3.5).

An operator is either an operator symbol, such as + or $$, or is an ordinary identifier enclosed in grave accents (backquotes), such as `op`. For example, instead of writing the prefix application op x y, one can write the infix application x `op` y. If no fixity declaration is given for `op` then it defaults to highest precedence and left associativity (see Section 4.4.2).

Dually, an operator symbol can be converted to an ordinary identifier by enclosing it in parentheses. For example, (+) x y is equivalent to x + y, and foldr (⋆) 1 xs is equivalent to foldr (\x y -> x⋆y) 1 xs.

所以这定义了两个概念,一个"operator symbol"和一个"operator"。 "operator symbol" 是任何符号标识符。 "operator" 是可以使用中缀语法应用的任何函数。

现在让我们一个一个地看你的例子:

第一个例子

(!#$%&*+./<=>?@\^|-~:) :: Int -> Int -> Int
a !#$%&*+./<=>?@\^|-~: b = a * b

标识符!#$%&*+./<=>?@\^|-~:是一个操作符号。如果用在中缀 位置,例如在此定义的左侧,它用作 运算符。

你给出两个使用例子:

λ: 10 !#$%&*+./<=>?@\^|-~: 20
200
λ: (!#$%&*+./<=>?@\^|-~:) 40 20
800

首先,我们将其用作运算符。在第二个,我们没有。

第二个例子

(!#$%&*+./<=>?@\^|-~:) :: Int -> Int
(!#$%&*+./<=>?@\^|-~:) a = a * a

同名,所以还是算符。该定义使用 括号形式,所以这里不用作运算符。

在你的例子中都没有:

λ: (!#$%&*+./<=>?@\^|-~:) 3 5 6
14
λ: (3 !#$%&*+./<=>?@\^|-~: 5) 6
14

两者都使用前缀语法。 语法上可以将其用作运算符,但它必然会产生类型错误。

第三个例子

(!#$%&*+./<=>?@\^|-~:) :: Int -> Int -> Int -> Int
(!#$%&*+./<=>?@\^|-~:) a b c = a + b + c

同样,它是同一个名字,所以它仍然是一个运算符符号。它在定义中没有用作运算符,因为它是前缀。

您的用例也使用前缀语法:

λ: (!#$%&*+./<=>?@\^|-~:) 3 5 6
14
λ: (3 !#$%&*+./<=>?@\^|-~: 5) 6
14

但是这个可以很容易地用在中缀位置,即作为运算符:

λ: (3 !#$%&*+./<=>?@\^|-~: 5) 6
14

又一个例子

考虑以下定义:

($$$) :: a -> a
($$$) x = x

这里,$$$也是一个运算符号。定义中没有将其用作运算符,而是以前缀表示法使用。但是,它也 可以 用于中缀位置,例如在

λ: negate $$$ 3
-3

结束语

非正式地,人们可能会在 Haskell 中以不一致的方式谈论函数和运算符,因为它们确实没有什么区别。一切都只是功能。能够在中缀符号中使用东西只是语法糖。所以在 Haskell 中编程很重要的是要知道句法规则,比如你可以用反引号将标识符括起来,或者用括号将符号括起来。了解 "operator" 的确切定义并不重要。那只是一个名字。