Das verhindert, dass sGegenstände innerhalb der STMonade nach außen aus der STMonade austreten .
let a = runST $ newSTRef (15 :: Int)
b = runST $ writeSTRef a 20
c = runST $ readSTRef a
in b `seq` c
Okay, dies ist ein Typfehler (was gut ist! Wir wollen nicht STRefaußerhalb der ursprünglichen Berechnung auslaufen!). Es ist ein Typfehler wegen des Extra s. Denken Sie daran, dass runSTdie Signatur hat:
runST :: (forall s . ST s a) -> a
Dies bedeutet, dass sfür die von Ihnen ausgeführte Berechnung keine Einschränkungen gelten müssen. Wenn Sie also versuchen zu bewerten a:
a = runST (newSTRef (15 :: Int) :: forall s. ST s (STRef s Int))
Das Ergebnis hätte einen Typ STRef s Int, was falsch ist, da der saußerhalb des forallIn "" entkommen "ist runST. Typvariablen müssen immer auf der Innenseite von a erscheinen forall, und Haskell erlaubt forallüberall implizite Quantifizierer. Es gibt einfach keine Regel, mit der Sie den Rückgabetyp von sinnvoll herausfinden können a.
Ein weiteres Beispiel mit forall: Um klar zu zeigen, warum Sie nicht zulassen können, dass Dinge einem entkommen forall, hier ein einfacheres Beispiel:
f :: (forall a. [a] -> b) -> Bool -> b
f g flag =
if flag
then g "abcd"
else g [1,2]
> :t f length
f length :: Bool -> Int
> :t f id
Dies ist natürlich f idein Fehler, da er entweder eine Liste Charoder eine Liste von zurückgeben würde, Intje nachdem, ob der Boolesche Wert wahr oder falsch ist. Es ist einfach falsch, genau wie das Beispiel mit ST.
Auf der anderen Seite, wenn Sie den sTypparameter nicht hätten , würde alles gut funktionieren , obwohl der Code offensichtlich ziemlich falsch ist.
Wie ST tatsächlich funktioniert: In Bezug auf die Implementierung ist die STMonade tatsächlich dieselbe wie die IOMonade, jedoch mit einer etwas anderen Schnittstelle. Wenn Sie die STMonade verwenden, erhalten Sie tatsächlich unsafePerformIOoder das Äquivalent hinter den Kulissen. Der Grund, warum Sie dies sicher tun können, liegt in der STTypensignatur aller verwandten Funktionen, insbesondere des Teils mit dem forall.