Eu tenho um tipo Id ae estou tentando evitar a coação acidental, por exemplo, um Id Doublepara um Id Int.
Se eu entendo as funções de digitação corretamente, o seguinte não deve ser compilado.
{-# 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)
Infelizmente, ele faz:
Prelude> :load Id.hs
[1 of 1] Compiling Main ( Id.hs, interpreted )
Ok, one module loaded.
*Main> :type badKey
badKey :: Id Int
O que estou perdendo nas funções de tipo?
type roleera fazer com que não fosse esse o caso. Esta pergunta está perguntando por que isso não funcionou.
ainIdé uma variável fantasma e não tem impacto no valor real interno. Se você tivessenewtype Id a = Id a, a coerção teria falhado.