2017-02-23 71 views
6

Uczę się Wiązu i znajduję wiele rzeczy, które są atrakcyjne, takie jak elegancja i prostota. Jednak jednym z aspektów, które uważam za zagadkowe, jest użycie "++" do łączenia łańcuchów. Na przykład:Dlaczego Elm używa operatora "++" do łączenia łańcuchów?

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

Dodawanie działa tak, jak można by tego oczekiwać.

> 2 + 3 + 9 
14 

Większość języków wysokiego poziomu, takich jak C#/Java/JavaScript/Python użyć jeden plus „+” w łączenie ciągów w analogiczny sposób wielokrotne numery będą sumowane. Wydaje się to o wiele bardziej intuicyjne, ponieważ istnieje pewna spójność w łączeniu łańcuchów, takich jak liczby sumujące.

Czy ktoś zna logikę stojącą za decyzją projektową, aby użyć ++ zamiast + w tym kontekście?

Odpowiedz

9

Wiąz umożliwia zdefiniowanie funkcji polimorficznych.

polimorfizm parametryczne gdy funkcja może być stosowany do elementów wszelkich typów:

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

ad-hoc, polimorfizm jest, gdy funkcja może być stosowany do elementów niektórych typów:

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

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

Zmienne typu number i appendable są specjalne, ponieważ reprezentują podzbiór wszystkich typów wiązów. List i Stringappendable typy podczas Float i Int są typy liczb.

To może być teoretycznie możliwe, aby zamiast zdefiniować zmienną hasPlus typu, które obejmowałoby List, String, Float i Int, ale potem podczas definiowania polimorficzny funkcję trzeba by mieć świadomość, że jest możliwe, że x + y jest inna niż y + x i byłoby to dużym obciążeniem, jeśli faktycznie myślisz o liczbach ...

6

Może to zapobiegać przeciążeniu operatora.

Przydatne może być statyczne określenie typów lub nawet poprawa czytelności, gdy zmienne są używane, ponieważ wtedy jest jasne, co się robi (połączenie ciągłe, jeśli ++ lub arytmetyczna, jeśli +).

W językach, które nie są silnie wpisane (nie wiem, czy tak jest w ELM), użycie tej samej notacji może uniemożliwić ustalenie, co jest robione na zmiennych przed rzeczywistym uruchomieniem programu, co powoduje, że wolniej.

XQuery używa także || zamiast +, niektóre języki używają różnych zapisów dziesiętnych, np. +. w CAML.

+0

Dzięki za odpowiedź. To zdecydowanie brzmi wiarygodne. Szukałem ostatecznej odpowiedzi online od Evan Czaplicki lub ktoś wtajemniczony w wewnętrzne działania ELM i nie był w stanie go znaleźć. Stąd moje pytanie. –

+0

Niektóre inne popularne języki, które nie przeciążają '+' dla konkatenacji, to PHP (używając '.') i ANSI SQL (używając' || '). –

+1

@DaveS Jeśli chcesz uzyskać odpowiedź od osoby z wewnątrz, powinieneś zapytać na liście mailingowej dev. –

4

Według docs operator ++ służy do wykazów załączonych:

-- 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 

Przed wersją 0.9, struny były reprezentowane jako Haskell inspirowane listy znaków. Wersja 0.9 wprowadziła nową bibliotekę ciągów (patrz tutaj: announcement), więc wygląda na to, że operator kontynuował pomimo, że ciągi nie są już reprezentowane jako lista.

+0

Z Elm Core Language Document - "Elm używa operatora (++), aby połączyć ciągi znaków.Zauważ, że oba ciągi znaków są zachowywane dokładnie tak, jak w przypadku ich połączenia, więc gdy połączymy" hello "i" world ", wynik bez odstępów." To, co mówisz, może równie dobrze być. Chciałbym uzyskać ostateczną odpowiedź. Do tej pory nie byłem w stanie go znaleźć, stąd moje pytanie. –

+0

Czy ++ jest ograniczone tylko do dołączania list i ciągów znaków? –

+0

[Wygląda na to] (http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Basics#++). – CodeMacabre

5

Konkatenacja i dodanie to zupełnie inne operacje o różnych właściwościach. Na przykład dodawanie jest przemienne (na liczbach całkowitych, zmienne są różnymi zwierzętami), a konkatenacja zdecydowanie nie jest. Arbitralna decyzja o ponownym użyciu operatorów przez niektóre języki jest najsilniejszym połączeniem między nimi.

A nawet gdyby przeciążenie miało sens, uderzyłbyś w statyczny charakter języka - jaki powinien być typ tego operatora?

Obecnie operator działa na magicznym typu number:

(+) : number -> number -> number 

Chociaż można mieć nową magiczną typ numberorstring i funkcję + byłby polimorficzny z dwóch różnych semantyki, to byłoby wprowadzenie tylko jeszcze bardziej magiczne język.

+0

Twoje poprawne, nie byłem precyzyjny w ostatniej części mojego pytania; tj. zmieniłem język z konkatenacji na sumę. Naprawiłem ten błąd. Dziękuję za wskazanie. –

+0

Nieco mylisz się, istnieje połączenie. (String, ++) i (List, ++) są monoidami, podczas gdy np. (Int, +) to grupa abelowa. Ale każda grupa to także monoid. Ale połączenie jest zbyt słabe IMO, aby było użyteczne w przypadku Wiązu. –

+0

Sądzę, że to jest jeden z powodów, dla których [jest zasadniczo możliwe zdefiniowanie nieprzemiennego dodatku na uogólnionych pierścieniach] (https://en.wikipedia.org/wiki/Near-semiring) (nie mówiąc o ograniczeniach) precyzyjne liczby zmiennoprzecinkowe, o których już wspomniałeś). W tym samym duchu jestem pewien, że istnieje pewien formalizm matematyczny, który pozwoliłby nam konsekwentnie definiować konkatenację jako rodzaj dodatku. –