Erkenne den unteren Wert in Haskell

8

Ich habe eine Haskell-Funktion geschrieben, die eine Liste xs in (init xs, last xs) wie folgt aufteilt:

%Vor%

Da eine leere Liste nicht auf diese Weise aufgeteilt werden kann, gibt es keine Übereinstimmung für die leere Liste. Allerdings wollte ich nicht einfach error ... der Funktion. Also habe ich folgendes definiert:

%Vor%

Dank der Lazy Evaluation kann ich ein sicheres init definieren, das einfach die leere Liste für die leere Liste zurückgibt:

%Vor%

Gibt es eine Möglichkeit, wie ich das undefinierte erkennen konnte, wenn ich versuchte, darauf zuzugreifen, so dass

%Vor%

Ich weiß über Maybe und Either , und dass diese eine bessere Wahl sind, um auszudrücken, was ich will. Allerdings habe ich mich gefragt, ob es einen Weg gibt, einen tatsächlichen Wert von undefiniert zu erkennen, d. H. In Bezug auf Fangfehler, wie das Abfangen von Ausnahmen.

    
scravy 22.02.2012, 09:27
quelle

5 Antworten

10

Da bottom subsumes non-termination beinhaltet, müsste die Funktion isUndefined das Halteproblem lösen und somit nicht existieren.

Aber beachte, dass selbst wenn es existiert, du immer noch nicht sagen könntest, ob der undefinierte Wert im 2. Element deines Tupels durch deine split -Funktion dort eingefügt wurde oder ob das letzte Element der Liste bereits undefiniert war.

    
Ingo 22.02.2012, 09:50
quelle
11

undefined ist nicht besser als mit error . Tatsächlich ist undefined in Prelude definiert als

%Vor%


Nun wird eine Funktion, die nicht zu einem error führen kann, eine "Gesamtfunktion" genannt, d. H. Sie ist für alle Eingabewerte gültig.

Die Funktion split , die Sie gerade implementiert haben, hat die Signatur

%Vor%

Dies ist ein Problem, da die Typ-Signatur verspricht, dass das Ergebnis immer eine Liste und ein Element enthält, was eindeutig unmöglich ist, leere Listen generischen Typs bereitzustellen.

Der kanonische Weg in Haskell, dies anzugehen, besteht darin, die Typ-Signatur zu ändern, um anzuzeigen, dass wir manchmal keinen gültigen Wert für den zweiten Gegenstand haben.

%Vor%

Jetzt können Sie eine korrekte Implementierung für den Fall schreiben, wo Sie eine leere Liste erhalten

%Vor%

Jetzt können Sie den Fall des fehlenden Werts durch Mustererkennung erkennen

%Vor%     
shang 22.02.2012 13:39
quelle
8

Die Funktion error tut nichts, bis sie ausgewertet wird. Sie können also beispielsweise Folgendes tun:

%Vor%     
Sjoerd Visscher 22.02.2012 09:41
quelle
4

Aus dem Haskell 2010 Language Report & gt; Einführung # Werte und Typen

  

Fehler in Haskell sind semantisch äquivalent zu ⊥ ("unten"). Technisch sind sie nicht von der Nicht-Terminierung zu unterscheiden, so dass die Sprache keinen Mechanismus zum Erkennen oder Handeln von Fehlern enthält.

Um klar zu sein, undefined soll eine Möglichkeit sein, ⊥ in Ihr Programm einzufügen, und da (wie oben erwähnt) undefined in error definiert ist, gibt es daher "nein" Mechanismus zum Erkennen oder Bewirken von undefined ".

    
Dan Burton 22.02.2012 14:41
quelle
1

Obwohl semantisch die Antwort von Ingo korrekt ist, wenn Sie GHC verwenden, gibt es einen Weg, der einige "unsichere" Funktionen verwendet, die zwar nicht ganz perfekt sind, aber eine Berechnung vom Typ IO a, die ein enthält Ausnahme wird zurückgegeben True, funktioniert. Es ist jedoch ein bisschen ein Betrüger:).

%Vor%

Ich weiß, das ist schrecklich, aber trotzdem funktioniert es. Es wird jedoch keine Beendigung feststellen;)

    
Julian Sutherland 15.07.2013 10:27
quelle

Tags und Links