Saya memiliki tipe Id a
dan saya mencoba untuk mencegah paksaan tanpa sengaja, misalnya, Id Double
ke Id Int
.
Jika saya memahami mengetikkan peran dengan benar, yang berikut ini tidak boleh dikompilasi.
{-# 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)
Sayangnya, itu tidak:
Prelude> :load Id.hs
[1 of 1] Compiling Main ( Id.hs, interpreted )
Ok, one module loaded.
*Main> :type badKey
badKey :: Id Int
Apa yang saya lewatkan tentang peran tipe?
type role
adalah untuk membuat itu tidak terjadi. Pertanyaan ini menanyakan mengapa itu tidak berhasil.
a
inId
adalah variabel phantom dan tidak berdampak pada nilai aktual di dalamnya. Jika Anda melakukannyanewtype Id a = Id a
, maka paksaan akan gagal.