Почему Elm использует оператор «++» для объединения строк?

Я изучаю Elm и нахожу в нем много привлекательных моментов, таких как элегантность и простота. Однако один аспект, который меня озадачивает, — это использование «++» для объединения строк. Например:

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

Дополнение работает так, как вы ожидаете.

> 2 + 3 + 9
14

Большинство языков высокого уровня, таких как C#/Java/JavaScript/Python, используют один плюс «+» в конкатенации строк аналогичным способом, которым суммируются несколько чисел. Это кажется намного более интуитивным, так как существует определенная согласованность в объединении строк, таких как суммирование чисел.

Кто-нибудь знает логику дизайнерского решения использовать ++ вместо + в этом контексте?


person Dave S    schedule 23.02.2017    source источник
comment
Сложение коммутативно. Добавление - нет.   -  person Titou    schedule 03.12.2019


Ответы (4)


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

Переменные типа number и appendable являются особыми, поскольку они представляют собой подмножество всех типов Elm. List и String — это типы appendable, а Float и Int — числовые типы.

Теоретически можно было бы вместо этого определить переменную типа hasPlus, которая включала бы List, String, Float и Int, но тогда при определении полиморфной функции вам нужно было бы знать, что возможно, что x + y отличается от y + x, и это будет довольно тяжело, если вы на самом деле думаете о числах...

person Zimm i48    schedule 23.02.2017

Конкатенация и сложение — совершенно разные операции с разными свойствами. Например, сложение является коммутативным (для целых чисел числа с плавающей запятой — разные звери), а конкатенация — определенно нет. Произвольное решение повторно использовать операторы некоторыми языками является самой сильной связью между ними, которую вы можете найти.

И даже если бы перегрузка имела смысл, вы бы задели статическую природу языка — какого типа должен быть такой оператор?

В настоящее время оператор работает с магическим типом number:

(+) : number -> number -> number

Хотя у вас мог бы быть новый магический тип numberorstring, а функция + была бы полиморфной с двумя разными семантиками, это только внесло бы в язык еще больше магии.

person Jan Tojnar    schedule 23.02.2017
comment
Вы правы, я не был точен в последней части своего вопроса; то есть я переключил свой язык с конкатенации на суммирование. Я исправил эту ошибку. Спасибо, что указали на это. - person Dave S; 23.02.2017
comment
Вы немного не правы, связь есть. (Строка, ++) и (Список, ++) являются моноидами, тогда как, например. (Int, +) — абелева группа. Но любая группа также является моноидом. Но связь слишком слабая IMO, чтобы быть полезной в случае с Elm. - person Zimm i48; 23.02.2017
comment
Я предполагаю, что это одна из причин, хотя в принципе возможно определить некоммутативное сложение на обобщенных кольца (не говоря уже о числах с плавающей запятой ограниченной точности, о которых вы уже упоминали). Точно так же я уверен, что существует некий математический формализм, который позволил бы нам последовательно определить конкатенацию как своего рода сложение. - person Konrad Rudolph; 23.02.2017
comment
@ Zimmi48, конечно, ты прав. Я знаю алгебру, но не хотел слишком углубляться в детали. Я отредактировал текст, чтобы сделать его более точным. - person Jan Tojnar; 23.02.2017

Это может быть сделано для того, чтобы избежать перегрузки оператора.

Может быть полезно статически выводить типы или даже улучшать читаемость при использовании переменных, поскольку тогда становится ясно, что делается (конкатенация строк, если ++, или арифметика, если +).

В языках, которые не являются строго типизированными (я не знаю, так ли это в Elm), использование одной и той же нотации может сделать невозможным узнать, что делается с переменными, до фактического запуска программы, что делает ее медленнее.

XQuery также использует || вместо +, некоторые языки даже используют другие обозначения для десятичных знаков, например +. в CAML.

person Ghislain Fourny    schedule 23.02.2017
comment
Спасибо за Ваш ответ. Это определенно звучит правдоподобно. Я искал окончательный ответ в Интернете от Эвана Чаплицки или кого-то, кто знаком с внутренней работой ELM, и не смог его найти. Отсюда мой вопрос. - person Dave S; 23.02.2017
comment
Некоторые другие основные языки, которые не перегружают + для конкатенации, — это PHP (с использованием .) и ANSI SQL (с использованием ||). - person Jan Tojnar; 23.02.2017
comment
@DaveS Если вам нужен ответ от инсайдера, вам следует задать вопрос в списке рассылки разработчиков. - person Zimm i48; 23.02.2017
comment
@ Zimmi48 - Я не знал, что мой вопрос был таким неясным. В любом случае. Я рад, что спросил об этом здесь, так как благодаря хорошо продуманным ответам я получаю много нового о языке. - person Dave S; 23.02.2017

Согласно документам, оператор ++ используется для добавления списков:

-- 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 появилась новая библиотека строк (см. объявление), поэтому она похоже, что оператор ++ сохранился, несмотря на то, что строки больше не представлены в виде списка.

person codemacabre    schedule 23.02.2017
comment
Из документа Elm Core Language — Elm использует оператор (++) для объединения строк. Обратите внимание, что обе строки сохраняются точно так же, как если бы они были собраны вместе, поэтому, когда мы объединяем приветствие и мир, результат не содержит пробелов. То, что вы говорите, вполне может быть. Хотелось бы увидеть исчерпывающий ответ. Пока не нашел, поэтому и вопрос. - person Dave S; 23.02.2017
comment
++ ограничен только добавлением списков и строк? - person Dave S; 23.02.2017
comment
Очевидно, так. - person codemacabre; 23.02.2017
comment
Мне кажется, что ++ можно назвать «присоединяющим» оператором - person Dave S; 02.03.2017