タイプがId a
あり、誤って強制的に変換しないようにしようとしId Double
ていId Int
ます。
タイプの役割を正しく理解していれば、以下はコンパイルできません。
{-# 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)
残念ながら、それはします:
Prelude> :load Id.hs
[1 of 1] Compiling Main ( Id.hs, interpreted )
Ok, one module loaded.
*Main> :type badKey
badKey :: Id Int
タイプロールについて何が不足していますか?
@lehinsのポイントは、そうで
—
ジョセフ・サイブル復活モニカ
type role
はないことです。この質問はそれがうまくいかなかった理由を尋ねています。
a
inId
はファントム変数であり、内部の実際の値には影響しません。もし持っていたらnewtype Id a = Id a
、強制は失敗したでしょう。