为什么 Elm 使用“++”运算符来连接字符串?

Why does Elm use the '++' operator to concatenate strings?

我正在学习 Elm,我发现它有很多吸引人的地方,比如它的优雅和简单。然而,我感到困惑的一个方面是它使用“++”来连接字符串。例如:

> "hello" ++ " world"
"hello world"

加法按照您期望的方式工作。

> 2 + 3 + 9
14

大多数高级语言(例如 C#/Java/JavaScript/Python)在连接字符串时使用单个加号“+”,类似于将多个数字相加的方式。它看起来更直观,因为在连接字符串时有一定的一致性,比如求和数字。

有人知道在这种情况下使用 ++ 而不是 + 的设计决策背后的逻辑吗?

这可能是为了避免运算符过载。

静态推断类型甚至在使用变量时提高可读性可能很有用,因为这样可以清楚地知道正在做什么(如果 ++ 则为字符串连接,如果 + 则为算术)。

在非强类型语言中(我不知道在 Elm 中是否属于这种情况),使用相同的符号可能会导致无法在实际 运行程序,这使它变慢了。

XQuery 也使用 || 而不是 +,某些语言甚至使用不同的小数表示法,例如 CAML 中的 +.

根据 docs++ 运算符用于附加列表:

-- alias for appending lists and two lists
append xs ys = xs ++ ys
xs = [1,2,3]
ys = [4,5,6]

-- All of the following expressions are equivalent:
a1 = append xs ys
a2 = xs ++ ys

b2 = (++) xs ys

c1 = (append xs) ys
c2 = ((++) xs) ys

在 0.9 版之前,字符串表示为受 Haskell 启发的字符列表。 0.9 版引入了一个新的字符串库(请参阅此处的 announcement),因此尽管字符串不再表示为列表,但看起来 ++ 运算符仍然存在。

Elm 允许您定义多态函数。

参数多态性是指函数可以应用于任何类型的元素:

f : (a, b) -> (b, a)
f (x, y) = (y, x)

临时多态性是指函数可以应用于某些类型的元素:

g : appendable -> appendable -> appendable -> appendable
g x y z = x ++ y ++ z

h : number -> number -> number
h x y = (x + 2) * y

类型变量 numberappendable 是特殊的,因为它们代表所有 Elm 类型的子集。 ListStringappendable 类型,而 FloatInt 是数字类型。

理论上可以定义一个 hasPlus 类型变量,其中包括 ListStringFloatInt,但随后在定义多态函数时,您需要注意 x + y 可能与 y + x 不同,如果您实际上在考虑数字,那将是一个很大的负担...

连接和加法是完全不同的运算,具有不同的性质。例如,加法是可交换的(在整数上,浮点数是不同的野兽),而连接绝对不是。某些语言重复使用运算符的任意决定是您可以找到的它们之间最牢固的联系。

即使重载有意义,您也会触及语言的静态性质——此类运算符的类型应该是什么?

目前运算符在魔法类型上工作number:

(+) : number -> number -> number

虽然你可以有一个新的魔术类型 numberorstring 并且 + 函数将是具有两种不同语义的多态,但这只会给语言引入更多的魔术。