Giả sử tôi đang viết một DSL và muốn hỗ trợ cả hỗ trợ kiểu ma và các biểu thức được nhập sai. các loại giá trị của tôi có thểGõ chữ GADTs
{-# LANGUAGE GADTs, DataKinds #-}
data Ty = Num | Bool deriving (Typeable)
data Val a where
VNum :: Int -> Val Num
VBool :: Bool -> Val Bool
và tôi có thể làm việc với một phantom xóa phiên bản
{-# LANGUAGE ExistentialQuantification #-}
data Valunk = forall a . Valunk (V' a)
Bây giờ, tôi có thể hoạt động trên các giá trị của Valunk
bởi case
ing ra cả VNum
và VBool
và thậm chí thiết lập lại phantom của tôi các loại theo cách này
getNum :: Valunk -> Maybe (Val Num)
getNum (Valunk [email protected](VNum _)) = Just n
getNum _ = Nothing
Nhưng điều này chỉ cảm thấy như tôi đang thực hiện lại Typeable
máy móc. Thật không may, GHC sẽ không cho phép tôi lấy được một Typeable
cho 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
Có cách nào để có được xung quanh hạn chế này? Tôi rất muốn viết
getIt :: Typeable a => Valunk -> Maybe (Val a)
getIt (Valunk v) = cast v
nhưng ngay bây giờ tôi phải dùng đến máy móc như thế này
class Typeably b x where kast :: x a -> Maybe (x b)
instance Typeably Num Val where
kast [email protected](VNum _) = Just n
kast _ = Nothing
cho tất cả các loại của tôi.
Nó loo ks giống như máy móc 'deriving (Typeable)' chưa được tạo để làm việc với 'DataKinds'. 'DataKinds' không cung cấp cho bạn bất cứ điều gì tuyệt vời, chỉ cần kiểm tra thêm một chút. Bạn có thể sử dụng 'dữ liệu Num' và' dữ liệu Bool' thay vì loại 'Ty' của bạn. – luqui