Załóżmy, że piszę DSL i chcę mieć wsparcie zarówno dla typów fantomowych, jak i źle wypisanych wyrażeń. Moje typy wartości mogą byćTypowe odlewanie GADTs
{-# LANGUAGE GADTs, DataKinds #-}
data Ty = Num | Bool deriving (Typeable)
data Val a where
VNum :: Int -> Val Num
VBool :: Bool -> Val Bool
i mogę pracować z fantomu skasowane wersja
{-# LANGUAGE ExistentialQuantification #-}
data Valunk = forall a . Valunk (V' a)
Teraz mogę pracować na wartościach Valunk
przez case
ing się zarówno VNum
i VBool
a nawet przywrócić mój fantom typy w ten sposób
getNum :: Valunk -> Maybe (Val Num)
getNum (Valunk [email protected](VNum _)) = Just n
getNum _ = Nothing
Ale to po prostu wydaje się być reimplementing Typeable
maszyn. Niestety, GHC nie pozwoli mi czerpać Typeable
dla 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
Czy istnieje sposób, aby obejść to ograniczenie? Chciałbym napisać
getIt :: Typeable a => Valunk -> Maybe (Val a)
getIt (Valunk v) = cast v
ale teraz muszę uciekać się do maszyn, jak to
class Typeably b x where kast :: x a -> Maybe (x b)
instance Typeably Num Val where
kast [email protected](VNum _) = Just n
kast _ = Nothing
dla wszystkich moich typów.
to loo ks jak maszyna 'pochodząca (Typeable)' nie została jeszcze stworzona do pracy z 'DataKinds'. 'DataKinds' nie daje nic niesamowitego, tylko trochę dodatkowego sprawdzenia. Możesz użyć 'danych Num' i' danych Bool' zamiast typu 'Ty'. – luqui