Ketik peran dan perilaku membingungkan dengan `memaksa`

11

Saya memiliki tipe Id adan saya mencoba untuk mencegah paksaan tanpa sengaja, misalnya, Id Doubleke 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?

Brice goreng
sumber
ain Idadalah variabel phantom dan tidak berdampak pada nilai aktual di dalamnya. Jika Anda melakukannya newtype Id a = Id a, maka paksaan akan gagal.
lehins
@ Bridgins Intinya type roleadalah untuk membuat itu tidak terjadi. Pertanyaan ini menanyakan mengapa itu tidak berhasil.
Joseph Sible-Reinstate Monica

Jawaban:

12

Coerciblememiliki tiga "jenis" yang mungkin dari instance (yang secara otomatis dihasilkan oleh kompiler, tidak ditentukan oleh pengguna). Hanya satu dari mereka yang benar-benar dipengaruhi oleh peran .

  • Setiap jenis bisa dipaksakan untuk dirinya sendiri.
  • Anda dapat memaksa "di bawah" konstruktor tipe, asalkan variabel tipe yang terpengaruh adalah representationalatau phantom. Misalnya, Anda dapat memaksa Map Char Intmenjadi Map Char (Data.Monoid.Sum Int)karena untuk Mapkita miliki type role Map nominal representational.
  • Anda selalu dapat memaksa tipe baru ke tipe yang mendasarinya dan sebaliknya, asalkan konstruktor tipe baru dalam ruang lingkup. Ini mengabaikan semua peran! Dasar pemikirannya adalah, mengingat konstruktor tersedia, Anda selalu dapat membungkus dan membuka bungkusan secara manual, sehingga peran tersebut tidak memberi Anda keamanan apa pun.

Dalam contoh Anda, aturan ketiga berlaku. Jika tipe baru telah didefinisikan dalam modul lain dan konstruktor tidak diimpor, paksaan akan gagal (untuk membuatnya bekerja lagi, Anda harus beralih peran ke phantom).

Perilaku khusus yang agak mengejutkan untuk tipe baru dijelaskan dalam masalah GHC ini .

danidiaz
sumber