2014-07-13 19 views
9

Control.Monad.ST nel pacchetto base contiene runST per eseguire il rigoroso dello stato-trasformatore monade:Questa generalizzazione di runST è sicura?

runST :: (forall s. ST s a) -> a 

Tuttavia, ho bisogno di una versione generalizzata di runST:

runSTCont :: (forall s . (forall b . ST s b -> b) -> a) -> a 
runSTCont f = f $ \m -> runST $ unsafeCoerce m 

La mia domanda è: questo uso di unsafeCoerse sicuro? (Credo di sì, perché, come ho capito, l'unico scopo dell'indice s è quello di impedire a trapelare s valori -indexed nel risultato a. Il tipo di runSTCont non può fuoriuscire s valori -indexed quindi dovrebbe essere OK.)

noti che runST può essere espresso in termini di runSTCont così runSTCont è almeno altrettanto generale runST:

runST' :: (forall s. ST s a) -> a 
runST' m = runSTCont $ \runST -> runST m 
+0

Potresti aggiungere un caso d'uso, perché hai bisogno di 'ruNSTCont'? –

+0

@ PetrPudlák, ho un caso d'uso complesso. Penso di poterlo semplificare, ma il caso d'uso più semplice è l'implementazione di 'runSTCont' stesso. Voglio evitare commenti come "questo caso d'uso potrebbe essere implementato anche con runST". –

risposta

12

io non la penso così:

crash = runSTCont crasher where 
    crasher :: forall s. (forall b . ST s b -> b) -> Integer 
    crasher go = 
    let r :: forall a. STRef s (a -> a) 
     r = go $ newSTRef id 
    in go $ do writeSTRef r (tail . tail) 
       f <- readSTRef r 
       return $ f (17 :: Integer) 

Il problema è che Haskell non ha la restrizione del valore.

+1

È il problema di questa particolare implementazione di 'runSTCont', o del suo tipo in generale? –

+1

@ PetrPudlák è un problema con il tipo in generale. Andrebbe bene se Haskell fosse call-by-name, ma poiché è implementato con call-by-need non è possibile generalizzare espressioni effectfull - anche se l'effetto (cioè heaplet che si modifica) è confinato in un "modulo" "che è ciò che' runSTCont' fa. –

+2

Mi piacerebbe capire meglio questa risposta. C'è un modo per cambiare il tipo fornito per renderlo sicuro. Sembra che l'attuale sia vicino a consentire, ma perde l'accesso a 'unsafeCoerce'. Questa funzione potrebbe essere implementata meglio se si avesse accesso ai costruttori ST? –

Problemi correlati