Предположим, я пишу DSL и хочу иметь поддержку как поддержки фантомного типа, так и плохо типизированных выражений. Мои типы значений могут бытьСмазываемые GADT
{-# 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 [email protected](VNum _)) = Just n
getNum _ = Nothing
Но это просто похоже на то,машины. К сожалению, GHC не позволит мне получить Typeable
для 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 [email protected](VNum _) = Just n
kast _ = Nothing
для всех моих типов.
It Лоо ks, как механизм «выводить (Typeable)», еще не создан для работы с DataKinds. 'DataKinds' не дает вам ничего удивительного, просто немного дополнительной проверки. Вы можете использовать 'data Num' и' data Bool' вместо своего типа 'Ty'. – luqui