Haskell - 限制数据参数

标签 haskell types restriction type-parameter custom-data-type

我正在尝试创建以下数据类型:

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) 

但是,正如评论中所示,我希望 ExprFuncall 旁边的 ExprValues 仅接受 ExprIdent String,而不是其他 ExprValues。我怎样才能做到这一点?

最佳答案

首先,如果您只想允许构造函数,为什么不直接“内联”它 - 将 String 存储在 ExprOverall 中并完成?

但更一般地说,这种限制可以通过 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 中使用,您选择一个仅适用于 ExprIdent 构造函数的唯一标记类型(因为它允许任何类型变量 a,而其他则特定于具体类型)。

data FreeIdentifier

data ExprOverall = ExprFunCall (ExprValues FreeIdentifier)

关于Haskell - 限制数据参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67445966/

相关文章:

Android:1024px 图像大小限制?

c - SSL BIO 和 FFI

arrays - 如何从一维数组中创建一个二维未装箱数组?

scala - scala 中并行或顺序收集的类型

windows-7 - Windows 7 功能区许可与 Office 2007 功能区许可

rest - 是否有 Google Cloud 项目 ID 的受限词列表?

haskell - 双感叹号有什么用?

shell - haskell 和 Unix shell 脚本

types - 尼姆 : "invalid type ... in this context" error

python - 正确使用 Python 泛型 - 如何获取泛型 var 的类型并在初始化后在对象内强制执行一致的类型?