私が DSL を書いていて、ファントム型のサポートと正しく型付けされていない式の両方をサポートしたいとしましょう。私の値のタイプは
{-# LANGUAGE GADTs, DataKinds #-}
data Ty = Num | Bool deriving (Typeable)
data Val a where
VNum :: Int -> Val Num
VBool :: Bool -> Val Bool
ファントム消去バージョンで作業できます
{-# LANGUAGE ExistentialQuantification #-}
data Valunk = forall a . Valunk (V' a)
これで、この方法でファントム タイプの両方を削除したり、再構築したりValunk
することで、 の値を操作できます。case
VNum
VBool
getNum :: Valunk -> Maybe (Val Num)
getNum (Valunk n@(VNum _)) = Just n
getNum _ = Nothing
Typeable
しかし、これは機械を再実装しているように感じます。Typeable
残念ながら、GHC ではfor を導出できません。Val
src/Types/Core.hs:97:13:
Can't make a derived instance of `Typeable (Val a)':
Val must only have arguments of kind `*'
In the data declaration for Val
この制限を回避する方法はありますか? ぜひ書きたい
getIt :: Typeable a => Valunk -> Maybe (Val a)
getIt (Valunk v) = cast v
しかし今、私はこのような機械に頼らなければなりません
class Typeably b x where kast :: x a -> Maybe (x b)
instance Typeably Num Val where
kast n@(VNum _) = Just n
kast _ = Nothing
私のすべてのタイプに。