Tengo un tipo Id ay estoy tratando de evitar la coerción accidental, por ejemplo, un Id Doublea un Id Int.
Si entiendo los tipos de letra correctamente, no se debe compilar lo siguiente.
{-# 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)
Lamentablemente, sí:
Prelude> :load Id.hs
[1 of 1] Compiling Main ( Id.hs, interpreted )
Ok, one module loaded.
*Main> :type badKey
badKey :: Id Int
¿Qué me estoy perdiendo sobre los roles de tipo?
type roleera hacer que ese no fuera el caso. Esta pregunta es por qué eso no funcionó.
ainIdes una variable fantasma y no tiene impacto en el valor real en su interior. Si lo hubiera hechonewtype Id a = Id a, entonces la coerción habría fallado.