Die Signatur von modifyIORef
ist einfach genug:
Leider ist das nicht Thread-sicher. Es gibt eine Alternative, die dieses Problem behebt:
%Vor% Was genau sind die Unterschiede zwischen diesen beiden Funktionen? Wie soll ich den Parameter b
verwenden, wenn ich eine IORef
ändere, die von einem anderen Thread gelesen werden kann?
Der zusätzliche Parameter wird verwendet, um einen Rückgabewert bereitzustellen. Beispielsweise möchten Sie möglicherweise den in IORef
gespeicherten Wert atomar ersetzen und den alten Wert zurückgeben. Sie können das so machen:
Wenn Sie keinen zurückzugebenden Wert haben, können Sie Folgendes verwenden:
%Vor%, das die gleiche Signatur wie modifyIORef
hat.
So verstehe ich das. Denken Sie an Funktionen, die dem Klammer-Idiom folgen, z. B.
%Vor% Diese Funktion nimmt eine Funktion als Argument und gibt den Rückgabewert dieser Funktion zurück. atomicModifyIORef
ist dem ähnlich. Es nimmt eine Funktion als Argument, und die Absicht ist, den Rückgabewert dieser Funktion zurückzugeben. Es gibt nur eine Komplikation: Die Argumentfunktion muss auch einen neuen Wert zurückgeben, der in IORef
gespeichert wird. Aus diesem Grund benötigt atomicModifyIORef
von dieser Funktion zwei Werte zurück. Natürlich ist dieser Fall mit dem Bracket-Fall nicht vollständig vergleichbar (z. B. gibt es keine IO
, wir befassen uns nicht mit der Ausnahmesicherheit usw.), aber diese Analogie gibt Ihnen eine Idee.
Die Art, wie ich das sehen möchte, ist über die State
Monad. Eine Stateful-Operation ändert einen internen Zustand und liefert zusätzlich eine Ausgabe. Hier befindet sich der Status in IORef
und das Ergebnis wird als Teil der Operation IO
zurückgegeben. Also können wir die Funktion mit State
wie folgt umformulieren:
Tags und Links haskell concurrency global-state