Haskell - 限制数据参数
Haskell - Restrict data parameters
我正在尝试创建以下数据类型:
data ExprValues = ExprNum Int |
ExprIdent String |
ExprChar Char |
ExprString String
deriving(Eq, Show, Read)
data ExprOverall = ExprFunCall ExprValues --correct this to use ExprIdent solely
deriving(Eq, Show, Read)
但是,正如评论中指出的那样,我希望 ExprValues 旁边的 ExprFuncall 接受 仅 ExprIdent String,不包括其他 ExprValues。我怎样才能做到?
首先,如果你只想允许构造函数,为什么不直接“内联”它——在 ExprOverall
中存储一个 String
就可以了?
但更一般地说,这种限制可以通过 GADT 来实现。通常,尤其是对于类似 AST 的类型,您希望表达表达式所代表的整体类型。在那里,ExprIdent
可能是多态的,而其他的是具体的:
{-# LANGUAGE GADTs #-}
data ExprValues a where
ExprNum :: Int -> ExprValues Int
ExprIdent :: String -> ExprValues a
ExprChar :: Char -> ExprValues Char
ExprString :: String -> ExprValues String
然后,为了在 ExprOverall
中使用,您 select 一个仅适用于 ExprIdent
构造函数的唯一标记类型(因为它允许任何类型变量 a
,而其他的则特定于具体类型)。
data FreeIdentifier
data ExprOverall = ExprFunCall (ExprValues FreeIdentifier)
我正在尝试创建以下数据类型:
data ExprValues = ExprNum Int |
ExprIdent String |
ExprChar Char |
ExprString String
deriving(Eq, Show, Read)
data ExprOverall = ExprFunCall ExprValues --correct this to use ExprIdent solely
deriving(Eq, Show, Read)
但是,正如评论中指出的那样,我希望 ExprValues 旁边的 ExprFuncall 接受 仅 ExprIdent String,不包括其他 ExprValues。我怎样才能做到?
首先,如果你只想允许构造函数,为什么不直接“内联”它——在 ExprOverall
中存储一个 String
就可以了?
但更一般地说,这种限制可以通过 GADT 来实现。通常,尤其是对于类似 AST 的类型,您希望表达表达式所代表的整体类型。在那里,ExprIdent
可能是多态的,而其他的是具体的:
{-# LANGUAGE GADTs #-}
data ExprValues a where
ExprNum :: Int -> ExprValues Int
ExprIdent :: String -> ExprValues a
ExprChar :: Char -> ExprValues Char
ExprString :: String -> ExprValues String
然后,为了在 ExprOverall
中使用,您 select 一个仅适用于 ExprIdent
构造函数的唯一标记类型(因为它允许任何类型变量 a
,而其他的则特定于具体类型)。
data FreeIdentifier
data ExprOverall = ExprFunCall (ExprValues FreeIdentifier)