Wie man den Wert einer Vielleicht in Haskell
Ich bin relativ neu in Haskell und begann zu Lesen, "Real World Haskell".
Ich stolperte über die Art Vielleicht und habe eine Frage, wie erhält man den tatsächlichen Wert von einer Just 1
zum Beispiel.
Habe ich geschrieben das folgenden code:
combine a b c = (eliminate a, eliminate b, eliminate c)
where eliminate (Just a) = a
eliminate Nothing = 0
Dies funktioniert gut, wenn ich:
combine (Just 1) Nothing (Just 2)
Aber wenn ich ändern, zum Beispiel 1 zu einem String funktioniert es nicht.
Ich glaube, ich weiß warum: weil eliminate
hat, zurück zu geben, eine Art, die ist in diesem Fall eine Int
. Aber wie kann ich das ändern eliminate
zu befassen, zumindest mit Strings (oder vielleicht mit allen Arten von)?
- Was sollte die Antwort für
Nothing
werden, wenn Sie erwarten einen string zurück? - Sie suchen ein token, das verwendet werden kann, um zu signalisieren "kein Ergebnis" für alle Typen... das ist genau das, was
Nothing
ist. Es ist keine totale FunktionMaybe a -> a
, weil es keine einheitliche Art und Weise ein, um eineNothing
in einea
. Das beste, was Sie tun können, ist eine Funktion schreiben, die(Maybe a, Maybe b, Maybe c) -> Maybe (a, b, c)
- möglich, Duplikat der Betrieb bei einer Rücksendung aus einer Vielleicht enthält "Nur"
- Wie ich gezeigt mit meine lächerlich lange Antwort, das problem ist anders als die, die TomMD verknüpft (in diesem einen, das Plakat erklärt, dass die Eingänge nie Nichts, in diesem Nichts ist explizit eine Möglichkeit, und in der Tat die Quelle für das problem geben)
- Vielleicht würde es helfen, wenn Sie uns sagen können, was du eigentlich machen willst. Möchten Sie vielleicht die "fromMaybe" - Funktion, oder möchten Sie vielleicht nutzen die Tatsache, dass Vielleicht ist eine Monade.
- hatte ich nicht etwas bestimmtes im Sinn. ich stolperte über die Vielleicht geben, die sich ein bisschen seltsam für mich. also versuchte ich eine Funktion schreiben, um wieder den ursprünglichen Wert.
- Recht, aber meine Antwort in diesem thread, die gerade lief, obwohl einige gemeinsame Wege, Sie befassen sich mit
Maybe a
(standard-Funktionen) und konzentrierte sich nicht auffromJust
oder andere Teiltöne als die einzige Möglichkeit. (Nicht, dass ich nicht einverstanden mit Ihrer Antwort, Lehr-typeclasses scheint eine gute Passform hier). - Möglich, Duplikat der Auspacken Datentypen in Haskell ohne überflüssigen code
Du musst angemeldet sein, um einen Kommentar abzugeben.
[edit vom Autor, 6 Jahre später] Dies ist eine unnötig lange Antwort, und ich bin nicht sicher, warum es akzeptiert wurde. Verwenden
maybe
oderData.Maybe.fromMaybe
wie vorgeschlagen, in der höchsten von Ihnen positiv bewertet werden Antwort. Was folgt, ist eher ein Gedanken-experiment eher als praktische Ratschläge.So, Sie versuchen, eine Funktion erstellen, die funktioniert für eine Reihe von verschiedenen Arten. Dies ist eine gute Zeit, um eine Klasse. Wenn Sie schon programmiert in Java oder C++ wird eine Klasse in Haskell ist eine Art, wie eine Schnittstelle in diesen Sprachen.
Diese Klasse definiert einen Wert
nada
, die soll Klasse sein äquivalentNothing
. Jetzt zum lustigen Teil: macht Instanzen dieser Klasse!Für einen Wert des Typs
Maybe a
, der Nichts-wie-Wert ist, gut,Nothing
! Das wird ein komisches Beispiel, in einer minute. Aber bevor dann, machen wir Listen eine Instanz dieser Klasse zu.Wird eine leere Liste ist eine Art, wie Nichts, richtig? Also für einen String (das ist eine Liste von Char), es wird ein leerer string zurückgegeben,
""
.Zahlen sind auch eine einfache Implementierung. Sie haben bereits angedeutet, dass 0 offensichtlich stellt das "Nichts" für zahlen.
Dieser wird tatsächlich nicht funktionieren, es sei denn, Sie setzen eine spezielle Zeile am Anfang der Datei
Oder wenn Sie Sie kompilieren können Sie die flags für diese Sprache pragmas. Mach dir keine sorgen über Sie, Sie sind nur die Magie, die macht mehr Sachen, die funktionieren.
So, jetzt haben Sie diese Klasse und diese Instanzen...jetzt lasst uns einfach neu schreiben Sie Ihre Funktion, Sie zu benutzen!
Bemerken, dass ich nur geändert
0
zunada
, und der rest ist die gleiche. Let ' s give it a spin!Sieht Super, Werte und Sachen. Beachten Sie die (Einfach Nichts), verwandelt sich in Nichts, sehen Sie? Das war ein komisches Beispiel, ein Vielleicht in ein Vielleicht. Anyways...was
eliminate Nothing
? Gut, der entstehende Typ ist mehrdeutig. Er weiß nicht, was wir erwarten. So haben wir zu sagen, was wir wollen.Gehen Sie voran und versuchen Sie es heraus für andere Arten; sehen Sie es bekommt
nada
für jeden. So, jetzt, wenn Sie diese Funktion verwenden mit Ihremcombine
- Funktion, erhalten Sie diese:Bemerken, die Sie noch haben, um anzuzeigen, welche Art Ihr "Nichts" ist, oder darauf hinweisen, was zurück geben, die Sie erwarten.
Oder Sie einschränken könnte die Typen, die Ihre Funktion erlaubt, indem es seine Art Signatur ausdrücklich in der Quelle. Dies macht Sinn, wenn die logische Verwendung der Funktion wäre, dass es nur mit den Parametern des gleichen Typs.
Nun es funktioniert nur, wenn alle drei Vielleicht Dinge, die sind vom gleichen Typ. Auf diese Weise wird es daraus schließen, dass die
Nothing
ist der gleiche Typ wie die anderen.Keine Zweideutigkeit, yay! Aber jetzt ist es ein Fehler, zu mischen und anzupassen, wie wir es zuvor getan haben.
Gut, ich denke, dass war eine ausreichend lange und übertrieben Antwort. Genießen.
Nothinglike
Arten, eingewickelt in ein Vielleicht. Aber wenn ein Typ nichtNothinglike
, dann warum würden Sie erwarten, dass diese Funktion, zu produzieren, ein Wert von diesem Typ, wenn Sie die Eingabe vonNothing
in den ersten Platz? 😉Vom standard
Prelude
,Erhält einen Standardwert wird, und eine Funktion, die Funktion anwenden, um den Wert in der
Maybe
oder Standardwert zurück.Ihre
eliminate
geschrieben werden konntemaybe 0 id
, z.B. gelten die identity-Funktion, oder 0 zurück.Vom standard
- Daten.Vielleicht
,Dies ist ein teilweise - Funktion (nicht mit return einen Wert für jede Eingabe, im Gegensatz zu einem insgesamt - Funktion, die das tut), sondern extrahiert den Wert, wenn möglich.
maybe
können Sie auchData.Maybe.fromMaybe :: a -> Maybe a -> a
eliminate = fromMaybe nada
Ich bin neu in Haskell auch, also ich weiß nicht, ob diese vorhanden ist, in die Plattform aber (ich bin sicher, es tut), sondern wie über ein "erhalten oder sonst" - Funktion, um einen Wert, wenn es vorhanden ist, sonst Rückgabe eines default?
fromMaybe
hackage.haskell.org/package/base-4.7.0.1/docs/...Dies ist die Antwort, die ich suchte, als ich kam auf diese Frage:
https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Maybe.html#v:fromJust
...und ebenso für
Either
:https://hackage.haskell.org/package/either-unwrap-1.1/docs/Data-Either-Unwrap.html
Bieten Sie Funktionen, die ich geschrieben hätte mich dem Auspacken den Wert aus seinem Kontext.
Den
eliminate
Funktion geben Sie die Signatur ist:Das ist, weil es gibt 0 zurück, auf Nichts, zwingt den compiler davon ausgehen, dass
a :: Int
in Ihremeliminate
Funktion. Damit der compiler leitet den Typ der Signatur dercombine
Funktion:... und das ist genau, warum es nicht funktioniert, wenn Sie eine Zeichenfolge übergeben, um es.
Wenn Sie schrieb es als:
dann würde es gearbeitet haben, mit einer Schnur oder mit jedem anderen Typ. Der Grund dafür beruht auf der Tatsache, dass
undefined :: a
, die machteliminate
polymorphe und anwendbar auf andere Typen als Int.Natürlich, das ist nicht das Ziel des Codes, d.h., um die combine-Funktion insgesamt.
In der Tat, selbst wenn eine Anwendung von
combine
einige Argumente Nichts gelingen würde (das ist, weil Haskell ist faul standardmäßig), sobald Sie versuchen, die Ergebnisse zu bewerten, Sie würde einen Laufzeitfehler erhalten, alsundefined
können nicht ausgewertet werden, um etwas sinnvolles (um es einfach auszudrücken).