Frage Ist `evaluate` sicher im Vergleich zu` seq`?


Wie in dieser Antwort gezeigt, seq kombiniert mit undefined macht sehr seltsame Dinge, wenn es um Gleichzeitigkeit geht, zum Beispiel kann es jede Monade zum Scheitern bringen. Ein anderes Beispiel ist in diese Frage.

Kürzlich bin ich gestolpert evaluate :: a -> IO a das macht eine ähnliche Sache - es wertet sein Argument WHNF aber nur aus, wenn das IO Aktion wird ausgewertet. Dies scheint viel sicherer zu sein, da man erwartet, dass " IO wir können alles machen. "Natürlich kann es nicht überall verwendet werden, aber oft ist die Notwendigkeit, einen Ausdruck auszuwerten, irgendwie mit einem verbunden IO Operation (möchte einen produzierenden Thread zwingen, eine Berechnung anstelle eines konsumierenden Threads beim Arbeiten auszuwerten MVars).

Also möchte ich fragen, wie sicher ist evaluate? Ist es möglich, Beispiele zu erstellen (involvieren IO natürlich), wo es Argumentation über Code wie bricht seq tut das? Oder kann ich es als einen sicheren Ersatz von betrachten? seq (wenn es für ein bestimmtes Programm möglich ist)?


10
2017-12-07 21:35


Ursprung


Antworten:


Nein, du bekommst immer noch die gleichen Probleme, die durch die verursacht werden seq Befehl, in dem jede Monade im ersten Argument von evaluate wird seine Monadenregeln gebrochen haben. In ertes 'Antwort auf die Regel:

In der Kleisli - Kategorie entsteht die Monade return ist der   Identitätsmorphismus und (<=<) ist Zusammensetzung. Damit return muss ein sein   Identität für (<=<):

return <=< x = x

Dies bedeutet, dass Sie in der Lage sein sollten, zu ersetzen return <=< x mit x mit irgendeiner gültigen Monade, ohne die Operation des Programms zu ändern.

Verwenden Sie das mit dem evaluate Funktion...

evaluate (return <=< undefined :: a -> Identity b) >> putStrLn "hello"

gibt hallo aus. Verwenden von was sollte eine äquivalente Aussage durch Ersetzen sein return <=< undefined mit undefined:

evaluate (undefined :: a -> Identity b) >> putStrLn "hello"

verursacht stattdessen ein Prelude.undefined Ausnahme.

Dies geschieht nur mit der Funktion evaluate. Beachte das return hat genau die gleiche Signatur wie evaluate. Wenn Sie ersetzen evaluate mit return In den obigen Befehlen ist die resultierende Aktion für beide Befehle gleich (sie geben aus hello).


5
2017-12-08 03:58