Schöne Möglichkeit, mehrere Referenzen zwischen Funktionen in ST monad zu verfolgen?

8

Ich schreibe einen Code (einen Metropolis-Hastings MCMC-Sampler), der einen Zufallszahlengenerator verwendet und ein Array und möglicherweise andere darauf basierende Strukturen modifiziert.

Meine ursprüngliche Idee war, die ST-Monade zu verwenden, so dass ich ST-Arrays und das mersenne-random-pure64-Paket verwenden konnte, wobei der PureMT-Generator als Teil des Zustands beibehalten wurde.

Ich möchte jedoch in der Lage sein, einen Teil der Arbeit in separate Hilfsfunktionen aufzuteilen (z. B. um eine zufällige Ganzzahl in einem gegebenen Bereich zu samplen, die Array-Struktur zu aktualisieren und möglicherweise kompliziertere Dinge). Um dies zu tun, müsste ich die Referenzen auf das PureMT gen und das Array an alle Funktionen übergeben, was schnell sehr hässlich werden könnte, wenn ich mehr Status speichern müsste.

Mein Instinkt besteht darin, den gesamten Staat in einem einzigen Datentyp zu gruppieren, auf den ich überall zugreifen kann, wie ich die State-Monade verwenden würde, indem ich einen neuen Datentyp definiere, aber ich weiß nicht, ob das mit der ST-Monade möglich ist oder der richtige Weg.

Gibt es irgendwelche schönen Muster, um so etwas zu tun? Ich möchte die Dinge so allgemein wie möglich halten, weil ich wahrscheinlich zusätzlichen Status hinzufügen und mehr monadischen Code um die vorhandenen Teile herum aufbauen muss.

Ich habe versucht, nach Beispielen für ST-Monad-Code zu suchen, aber es scheint nicht in Real World Haskell enthalten zu sein, und die Haskell-Wiki-Beispiele sind sehr kurz und einfach.

Danke!

    
Tom 10.08.2011, 13:36
quelle

2 Antworten

10
  

Mein Instinkt besteht darin, den gesamten Staat in einem einzigen Datentyp zu gruppieren, auf den ich überall zugreifen kann, wie ich die State-Monade verwenden würde, indem ich einen neuen Datentyp definiere, aber ich weiß nicht, ob das mit der ST-Monade möglich ist oder der richtige Weg.

     

Gibt es irgendwelche schönen Muster, um so etwas zu tun? Ich möchte die Dinge so allgemein wie möglich halten, da ich wahrscheinlich zusätzlichen Status hinzufügen und mehr monadischen Code um die vorhandenen Teile herum erstellen muss.

Der entscheidende Punkt hier ist, dass es völlig irrelevant ist, dass Sie ST verwenden. Die ST -Referenzen selbst sind nur normale Werte, auf die Sie an verschiedenen Stellen zugreifen müssen, aber Sie wollen sie eigentlich nicht ändern! Die Änderbarkeit tritt in ST auf, aber die Werte für STRef und was nicht, sind grundsätzlich schreibgeschützt. Sie sind Namen , die auf die veränderbaren Daten zeigen.

Natürlich ist der schreibgeschützte Zugriff auf eine Umgebungsumgebung das, wofür die Reader -Monade ist. Die hässliche Weitergabe von Referenzen an alle Funktionen ist genau das, was es für dich tut, aber weil du schon in ST bist, kannst du es einfach als Monad Transformer anschalten. Als einfaches Beispiel können Sie Folgendes tun:

%Vor%

Im Allgemeinen könnten Sie über die Details der Referenztypen abstrahieren und zu einer allgemeinen "Umgebung" machen mit veränderbaren Referenzen "Monad.

    
C. A. McCann 10.08.2011, 15:48
quelle
5

Sie können die ST-Monade genauso wie die IO-Monade verwenden, wobei Sie berücksichtigen, dass Sie nur Arrays und Refs und keine anderen IO-Goodies erhalten. Genau wie bei IO können Sie ein StateT darüber schichten, wenn Sie einen bestimmten Status transparent durch Ihre Berechnung fädeln möchten.

    
sclv 10.08.2011 14:46
quelle

Tags und Links