Frage

Ich habe eine Funktion in Haskell geschrieben, die ein paar Parameter wie Word32, String (Currying ignorieren) akzeptiert und IO Word32 ausgibt.Nun, das ist ein Funktion im wahrsten Sinne des Wortes: Bei gleichen Eingaben ist die Ausgabe immer gleich.Es gibt keine Nebenwirkungen.Der Grund dafür, dass die Funktion IO Word32 anstelle von Word32 zurückgibt, besteht darin, dass die Funktion viele 32-Bit-Linear-Feedback-Schieberegister (lfsr) und andere Register mehrmals in einer Schleife aktualisiert, um die endgültige Word32-Ausgabe zu berechnen.

Meine Frage ist diese:Angesichts dieser Funktion hat praktisch keine Nebenwirkungen, Ist es möglich, diese Registeraktualisierungen innerhalb der Funktionsimplementierung auszublenden, sodass die Funktion Word32 und nicht IO Word32 zurückgibt?Wenn das so ist, wie?

War es hilfreich?

Lösung

Ja!Haskell kann dies tun.

Die ST-Monade

Wenn Sie tatsächlich veränderliche Zustände (Register) verwenden, die dem Beobachter außerhalb der Funktion vollständig verborgen bleiben, dann sind Sie dabei die ST-Monade, eine Monade nur für Memory-Effekte.In die ST-Welt gelangen Sie über runST, und wenn Sie die Funktion verlassen, sind garantiert nicht alle Effekte sichtbar.

Es ist genau die richtige Rechenumgebung für die Arbeit mit lokalen, veränderlichen Zuständen.

Rein funktionsfähiger Zustand:die Staatsmonade

Wenn Sie jedoch nicht tatsächlich Register oder Zellen ändern, sondern einen rein funktionalen Wert mehrmals aktualisieren, steht Ihnen eine einfachere Umgebung zur Verfügung: die Staatsmonade.Dies erlaubt keinen veränderlichen Zustand, sondern vermittelt die Illusion eines lokalen Zustands.

IO und unsicherPerformIO

Wenn Sie schließlich lokale, veränderliche Effekte haben, wie im ST monad, aber aus irgendeinem Grund benötigen Sie E/A-Operationen für diesen Zustand (z. B. über einen FFI-Aufruf), Sie können das simulieren ST monad, mit fast genauso viel Sicherheit, durch die Verwendung unsafePerformIO, anstatt runST, um eine lokale E/A-Umgebung einzuführen.Da die E/A-Monade keine netten Typen zum Erzwingen der Abstraktion hat, müssen Sie manuell sicherstellen, dass die Nebenwirkungen nicht beobachtbar sind.

Andere Tipps

Wenn Sie diese Funktion mit dem FFI importiert haben, entfernen Sie einfach die IO vom Rückgabetyp.Ansonsten verwenden unsafePerformIO :: IO a -> a aus System.IO.Unsafe.Bitte beachten Sie, dass diese Funktion eine der gefährlichsten Funktionen in Haskell ist.Verwenden Sie es nicht, wenn Sie sich über die Konsequenzen nicht wirklich im Klaren sind.Aber für deinen Zweck scheint es in Ordnung zu sein.

Ja, dies wäre eine legitime Verwendung von UNSAFEPERFORMIO. Aber es ist nur in Ordnung, wenn Sie wirklich sicher sind, dass es keine sichtbaren Wirkungen gibt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top