Ho una situazione in cui sono al momento utilizzando la funzione estremamente spaventosa unsafeCoerce. Non è per niente importante per fortuna, ma mi chiedevo se questo sembra essere un uso sicuro di questa funzione, o se ci sarebbe un altro modo per risolvere questo particolare problema che altre persone conoscono.Si tratta di un uso sicuro di unsafeCoerce?
Il codice che ho è qualcosa di simile al seguente:
data Token b = Token !Integer
identical :: Token a -> Token b -> Bool
identical (Token a) (Token b) = a == b
data F a = forall b. F (Token b) (a -> b)
retrieve :: Token b -> F a -> Maybe (a -> b)
retrieve t (F t' f) = if identical t t' then Just (unsafeCoerce f) else Nothing
Due cose aggiuntive da notare, sono che questi segnalini sono utilizzati all'interno di una monade che io uso per garantire che la fornitura di interi per loro è unico (cioè non faccio lo stesso token due volte). Io uso anche una variabile di tipo shadow foriforme quantificata, allo stesso modo della monade ST, per assicurarmi che (assumendo solo i metodi che espongo nel modulo vengano usati) non c'è modo di restituire un token (o in realtà anche un F) dalla monade senza che si tratti di un errore di tipo. Inoltre non espongo il costruttore di token.
Penso che, per quanto posso vedere, questo dovrebbe essere un uso sicuro di unsafeCoerce, come posso dire con (spero) abbastanza alta fiducia che il valore che sto costringendo è in realtà esattamente il tipo che io lo sto costringendo a, ma potrei sbagliarmi. Ho anche provato a usare Data.Typeable, che funziona bene, ma al momento sto cercando di evitare il vincolo Typeable, specialmente visto che gcast sembra fare qualcosa in molti modi simili, e comunque avrei comunque bisogno dei token per distinguere tra F diverse dello stesso tipo.
Grazie mille per qualsiasi aiuto/consiglio.
Questo assomiglia molto a 'Data.Typeable' che usa' unsafeCoerce' sotto le copertine per implementare 'cast'. –
È molto simile, infatti Iirc I aveva detto tanto nell'ultima parte dell'ultimo paragrafo della domanda. Grazie comunque. – DarkOtter
Se si copia in modo efficace 'cast', l'uso di' unsafeCoerce' è sicuro, ma si perde il compilatore generato 'typeOf' /' TypeRep'. Puoi prendere in considerazione l'uso di 'TypeRep' invece di' Integer' nel tuo token. –