Zufällig als Instanz von scalaz.Monad

8

Dies ist ein Follow-up zu meiner vorherigen Frage . Ich schrieb eine Monade (für eine Übung), die eigentlich eine Funktion ist, die Zufallswerte erzeugt. Es ist jedoch nicht als -Instanz der Typklasse scalaz.Monad definiert.

Nun habe ich mir die Rng Bibliothek angesehen und festgestellt, dass sie Rng als scalaz.Monad definiert hat:

%Vor%

Ich frage mich also, wie genau die Nutzer davon profitieren. Wie können wir die Tatsache nutzen, dass Rng eine Instanz der Typklasse scalaz.Monad ist? Können Sie Beispiele nennen?

    
Michael 23.11.2014, 15:27
quelle

3 Antworten

3

Einer der Vorteile ist, dass Sie viele nützliche Methoden in MonadOps erhalten.

Zum Beispiel erzeugt Rng.double.iterateUntil(_ < 0.1) nur die Werte, die kleiner als 0.1 sind (während die Werte größer als 0.1 übersprungen werden).

iterateUntil kann für die Erzeugung von Verteilungsmustern mithilfe einer Zurückweisungsmethode verwendet werden. Z.B. Dies ist der Code, der einen Beta-Verteilungs-Sample-Generator erzeugt:

%Vor%     
ZhekaKozlov 24.11.2014, 09:09
quelle
7

Hier ist ein einfaches Beispiel. Angenommen, ich möchte eine zufällige Größe für einen Bereich auswählen und dann einen zufälligen Index innerhalb dieses Bereichs auswählen und dann sowohl den Bereich als auch den Index zurückgeben. Die zweite Berechnung eines Zufallswertes hängt eindeutig von der ersten ab - ich muss die Größe des Bereichs kennen, um einen Wert im Bereich auszuwählen.

Diese Art der Sache ist spezifisch, was monadische Bindung für ist - es erlaubt Ihnen, folgendes zu schreiben:

%Vor%

Dies wäre nicht möglich, wenn wir keine Monad -Instanz für Rng hätten.

    
Travis Brown 23.11.2014 16:21
quelle
2

Wie jede Schnittstelle hat das Deklarieren einer Instanz von Monad[Rng] zwei Dinge: Sie stellt eine Implementierung der Methoden Monad unter Standardnamen bereit und drückt einen impliziten Vertrag aus, dass diese Methodenimplementierungen bestimmten Gesetzen entsprechen (in diesem Fall) , die Monadengesetze).

@Travis gab ein Beispiel für eine Sache, die mit diesen Schnittstellen implementiert wurde, die Scalaz-Implementierung von map und flatMap . Du hast recht, dass du diese direkt umsetzen kannst; Sie sind in Monad "geerbt" (eigentlich ein bisschen komplexer als das).

Als Beispiel für eine Methode, für die Sie definitiv eine Scalaz-Schnittstelle implementieren müssen, wie wäre es mit sequence ? Dies ist eine Methode, die einen List (oder allgemeiner ein Traversable ) von Kontexten in einen einzelnen Kontext für ein List umwandelt, z. B.:

%Vor%

Aber das verwendet eigentlich nur Applicative[Rng] (was eine Superklasse ist), nicht die volle Potenz von Monad . Ich kann nicht wirklich an etwas denken, das Monad direkt verwendet (es gibt ein paar Methoden auf MonadOps , zB untilM , aber ich habe noch nie einen von ihnen in Wut benutzt), aber vielleicht möchtest du ein Bind für einen "Wrapper" -Fall, in dem Sie eine "innere" Monad "innerhalb" Ihrer Rng sachen haben, in diesem Fall ist MonadTrans nützlich:

%Vor%

Um ganz ehrlich zu sein, ist Applicative wahrscheinlich gut genug für die meisten Monad Anwendungsfälle, zumindest die einfacheren.

Natürlich sind all diese Methoden Dinge, die Sie selbst implementieren können, aber wie jede Bibliothek ist der ganze Sinn von Scalaz, dass sie bereits implementiert sind und unter Standardnamen, was es für andere einfacher macht Leute, die Ihren Code verstehen.

    
lmm 24.11.2014 10:52
quelle

Tags und Links