Digita ruoli e comportamento confuso con `coerce`


11

Ho un tipo Id ae sto cercando di prevenire la coercizione accidentale, ad esempio, da an Id Doublea an Id Int.

Se capisco correttamente i ruoli di tipo, non dovrebbe essere compilato quanto segue.

{-# LANGUAGE RoleAnnotations #-}
import Data.Coerce (coerce)

type role Id nominal
newtype Id a = Id String

badKey :: Id Int
badKey = coerce (Id "I point to a Double" :: Id Double)

Sfortunatamente, fa:

Prelude> :load Id.hs
[1 of 1] Compiling Main             ( Id.hs, interpreted )
Ok, one module loaded.
*Main> :type badKey
badKey :: Id Int

Cosa mi manca dei ruoli di tipo?


ain Idè una variabile fantasma e non ha alcun impatto sul valore reale all'interno. Se lo avessi fatto newtype Id a = Id a, la coercizione sarebbe fallita.
lehins,

@lehins Il punto è type rolestato quello di non farlo. Questa domanda è: perché non ha funzionato.
Joseph Sible: ripristina Monica il

Risposte:


12

Coercibleha tre possibili "tipi" di istanze (che sono generati automagicamente dal compilatore, non definiti dall'utente). Solo uno di essi è effettivamente influenzato dai ruoli .

  • Ogni tipo è coercibile a se stesso.
  • Puoi forzare "sotto" un costruttore di tipi, a condizione che le variabili di tipo interessate siano representationalo phantom. Ad esempio, puoi forzare a Map Char Intin a Map Char (Data.Monoid.Sum Int)perché per Mapnoi type role Map nominal representational.
  • Puoi sempre forzare un newtype nel tipo sottostante e viceversa, a condizione che il costruttore newtype rientri nell'ambito. Questo ignora tutti i ruoli! La logica è che, dato che il costruttore è disponibile, potresti sempre avvolgere e scartare manualmente, quindi il ruolo non ti dà comunque sicurezza.

Nel tuo esempio, si applica la terza regola. Se il newtype fosse stato definito in un altro modulo e il costruttore non fosse stato importato, la coercizione sarebbe fallita (per farlo funzionare di nuovo, dovrai cambiare il ruolo phantom).

Il comportamento speciale piuttosto sorprendente per i newtypes è spiegato in questo numero di GHC.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.