Wie verhält sich die Vielleicht-Monade zum Optionstyp?

8

Ich hielt eine Präsentation über F # und diskutierte den Optionstyp, als mich jemand im Publikum fragte, ob der Optionstyp die Implementierung der Vielleicht-Monade durch F # ist. Ich weiß, dass dies nicht der Fall ist, aber ich wollte fragen, wie die beiden Konzepte zusammenhängen. Ich meine, es scheint mir, dass ein Optionstyp das Ergebnis der Operation einer vielleicht Monade sein könnte, aber ich bin mir nicht einmal sicher.

Würde jemand die Beziehung zwischen der vielleicht Monade und dem Optionstyp in den funktionalen Sprachen erläutern, die dies unterstützen?

Onorio Catenacci
quelle
4
Nur neugierig, aber woher weißt du das that's not the case? Sie sehen mir sehr ähnlich.
Deshalb frage ich.
Onorio Catenacci

Antworten:

8

Wenn man die Dokumentation zum OptionTyp von F # liest , sieht es so aus, als ob es sich ziemlich genau wie der MaybeTyp in Haskell verhält , da es entweder 'nichts' ( Nonein F #, Nothingin Haskell) oder einen Wert seines Argumenttyps ( Somein F #, ) modellieren kann. Justin Haskell).

In Haskell handelt es sich jedoch Maybeauch um eine Monade, und die Installation ist so, dass Berechnungen von MaybeWerten möglich sind und frühzeitig zurückgegeben werden, Nothingwenn eine der Variablen in der Berechnung vorhanden ist Nothing. Auf diese Weise Maybewird ein einfacher Fehlerbehandler (oder besser gesagt ein Gerät, das Fehler ignoriert) verwendet, und die Tatsache, dass es sich um eine Monade handelt, ermöglicht es, die Kesselplatte aus dem Weg zu räumen. In diesem Wikipedia-Artikel finden Sie ein schönes, kurzes Beispiel. Ich glaube nicht, dass Optiondiese Art der monadischen Verwendung unterstützt wird (tatsächlich frage ich mich, ob es überhaupt ein explizites Konzept einer Monade in F # gibt). Wenn Sie dieses Verhalten in .NET wünschen, würden Sie es vermutlich Option.Valuefür alle Ihre Argumente verwenden und die gesamte Berechnung in einen Versuch / Fang einschließen NullReferenceException.

Obwohl Optiones dem Maybe Typ ähnlich ist , entspricht es nicht der Maybe Monade .

tdammers
quelle
Danke für die klare Erklärung. Ehrlich gesagt habe ich immer gedacht, dass sie nicht gleich sind (einer ist ein Typ, der andere eine Monade), aber mir war nicht ganz klar, wie einer mit dem anderen zusammenhängt.
Onorio Catenacci
Übrigens - es gibt eine Art Monadenkonzept in F #; Es wird als Berechnungsausdruck bezeichnet.
Onorio Catenacci
@OnorioCatenacci: Ah, OK. Ich hatte nicht viel F # -Belichtung, also entschuldigen Sie mich. Wie auch immer, in Haskell, Monaden sind Typen, insbesondere Arten der Monadtypeclass. Maybeist ein einfacher alter Datentyp, der jedoch auch implementiert wird Monad, um dieses "spezielle" Verhalten bereitzustellen.
tdammers
2
Kurz gesagt: Ich stimme überhaupt nicht zu, dass sie nicht gleichwertig sind. Sprachkonstrukte wie Typklassen oder Polymorphismus ändern die grundlegenden mathematischen Eigenschaften und Strukturen eines Typs nicht.
Sara
2
Die Optionen mapund bindFunktionen von F # verhalten sich identisch mit den Vielleicht fmapund bindFunktionen von Haskell . Sie sind beide Monaden und haben ein gleichwertiges monadisches Verhalten. Haskell hat nur eine MonadTypklasse, mit der Sie Monaden manipulieren können, während sie in F # eher einem abstrakten "Designmuster" ähneln.
Jack
9

Ja, sie sind in dem Sinne äquivalent, dass der OptionTyp zusammen mit Option.bindund der SomeTypkonstruktor eine Monade bilden.

Während Monaden (wie in der MonadTypklasse) ein zentraler Bestandteil von Haskells Identität sind, sind sie aus konzeptioneller Sicht ein sprachunabhängiges Konstrukt. Ein Designmuster, wenn Sie möchten. Wenn Sie einen Typ haben und eine Bindungs- und eine Rückgabefunktion mit bestimmten Signaturen haben, die bestimmten Gesetzen entsprechen - Sie haben eine Monade -, unabhängig von der Sprache, die Sie verwenden.

F # -Berechnungsausdrücke bieten nur einen programmierbaren Syntaxzucker für Monaden, ähnlich der do-Notation in Haskell. Obwohl kein OptionBuilder für Berechnungsausdrücke standardmäßig bereitgestellt wird, können Sie auf einfache Weise einen Bare-Bones wie diesen definieren:

type OptionBuilder () = 
    member this.Bind(m, f) = Option.bind f m
    member this.Return(a) = Some a 

let option = OptionBuilder ()  

Und benutze es so:

let c = 
    option {
        let! a = Some 4
        let! b = None
        return a + b
    }

Das ist ein gezuckertes Äquivalent von so etwas:

let c =
    (Some 4) 
    |> Option.bind (fun a ->
        None 
        |> Option.bind (fun b ->
             Some (a + b)))

Beachten Sie, wie die Builder-Mitglieder die MonadTypklasse spiegeln und wie Sie monadischen - auch wenn verschlungenen - Code ohne Builder schreiben können.

scrwtp
quelle
3

Sie sind gleichwertig und beide Monaden. Der Unterschied wird ein Monade Mittel etwas in Haskell - es gibt eine explizite Monadtypeclass und „do - Notation“ verwendet wird , kann eine Menge von vorformulierten zu beseitigen , wenn monadischen Code zu schreiben. In F # kann die Builder-Notation und let!und do!verwendet werden, um ähnliche Boilerplates zu entfernen, aber es gibt keine explizite Vorstellung von einem Typ "eine Monade sein". Das MonadTypensystem von Haskell umfasst Typklassen (von denen die allgemeine Klasse ist) und höher sortierte Typen (von denen eine Person Monadist), die das Schreiben von Code ermöglichen, der für alle Monaden funktioniert. Das Typensystem von F # verfügt über keine dieser Funktionen.

Also ja, F # Optionund Haskell Maybesind identisch und beide Monaden. Es ist nur so, dass Haskell Ihnen viel mehr Maschinen zum Arbeiten mit Monaden bietet als F #.

Jack
quelle