Warum hat Haskell "wenn / dann / sonst" eingebaut, anstatt es als einfache Bibliotheksfunktion zu definieren?

25

Warum hat Haskell eine eingebaute if/then/else, typabhängige Bool, anstatt eine einfache Bibliotheksfunktion? Sowie

if :: Bool -> a -> a -> a
if True  x _ = x
if False _ y = y
Petr Pudlák
quelle
4
Ich denke, sie wollten explizit die if / then / else-Syntax, die sie ohne Mixfix-Funktionen wie in agda nicht bekommen können. Die Funktion, auf die Sie sich beziehen, ist als ternär strukturiert, die Sie selbst implementieren könnten, obwohl sie uns vermutlich gegeben haben, wenn / dann / sonst Zucker (es ist wahrscheinlich nur Zucker über einem Fall), nur weil sie könnten und es harmlos ist. Aber ich habe nichts um mich hier zu unterstützen, weshalb ich dies in einem Kommentar schreibe.
Jimmy Hoffa
10
Dies mag für die meisten Leser offensichtlich sein, aber ich möchte darauf hinweisen, dass es in einer eifrigen Sprache (z. B. Schema oder sml) keine gute Lösung wäre, wenn / then / else als Funktion verwendet wird, während dies in einer faulen Sprache sinnvoll ist Sprache wie Haskell.
Giorgio,

Antworten:

24

Es ist rein für den schönen Zucker von den if, thenund elseSchlüsselwort; Tatsächlich wird GHC (mit RebindableSyntaxaktivierter Erweiterung) die Syntax desugarisieren, indem einfach die ifThenElseFunktion aufgerufen wird, die sich im Gültigkeitsbereich befindet.

Pthariens Flamme
quelle
6

Es macht nicht viel aus ... für mich sieht es so aus, als würde / dann / sonst heutzutage nicht sehr oft verwendet. Ich schreibe Pattern Guards anstelle von if .. then .. else.

Aus syntaktischer Sicht ist es jedoch schön zu haben

if expr1 then expr2 else expr3

Du kannst also schreiben

if foo a then bar b else baz c

anstatt

if (foo a) (bar b) (baz c)

das sieht mir ein bisschen zu lissisch aus.

Für die semantische Analyse und Codegenerierung ist es schön, dieses Konstrukt zu haben, das leicht zu effizientem Maschinencode kompiliert werden kann. Beachten Sie, dass der Code im Gegensatz zu einem Funktionsaufruf, bei dem alle (nicht ausgewerteten) Parameter übergeben werden müssen, den Teil überspringen kann, der den Thunk für den Zweig erstellt, der nicht erreicht wird. Es kostet aber auch Zeit (und Speicher, der später wiederhergestellt werden muss), um den Thunk zu erstellen. Um dies wieder gut zu machen, müsste man die if-Funktion überall einbinden.

Ingo
quelle
3
Ich denke nicht, dass das Inlining ein aktuelles Problem ist. Ich verstehe, dass GHC bereits außergewöhnlich gut darin ist, kleine Funktionen zu inlinen, weil es in Haskell nur ein so verbreitetes Muster ist.
Tikhon Jelvis
1
@TikhonJelvis Sicher, aber mit if / then / else brauchst du keine spezielle Funktion, die immer eingebunden werden muss. Sie benötigen nicht einmal einen Inlining-Pass und können dennoch anständigen Code generieren. Nicht die ganze Welt ist GHC.
Ingo