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)