2
我是Haskell的初学者,正在解析和构建AST。我想知道如何定义类型如下:使一种类型成为一种类型或另一种类型
A Value
可以是Identifier
或Literal
。现在,我只是有一种Value
有两个构造函数(取标识符的名称和字符串常量的值分别为):
data Value = Id String
| Lit String
不过,后来想创建一个表示在一个分配的类型AST,所以我需要像
data Assignment = Asgn Value Value
但显然,我总是想一个Assignment
的第一部分,始终是一个Identifier
!所以我想我应该让Identifier
和Literal
不同的类型,以便更好地辨别事情:
data Identifier = Id String
data Literal = Lit String
但我怎么现在定义Value
?我thaught的是这样的:
-- this doesn't actually work...
data Value = (Id String) -- How to make Value be either an Identifier
| (Lit String) -- or a Literal?
我知道我可以简单地做
data Value = ValueId Identifier
| ValueLit Literal
但是这让我觉得有点unelegant和让我不知道是否有更好的解决办法?
你可能想看看[GADTs](https://en.wikibooks.org/wiki/Haskell/GADT)。既然'Id'和'Lit'现在都是基于'String'的,现在你可能想用一些额外的参数来区分这两种类型(可能是一个幻象类型变量)。 –
我不认为数据值= ValueId标识符| ValueLit Literal'不够好看。你不喜欢它什么? - 顺便提一下,注意通常我们更喜欢编写'newtype Identifier = Id String',而不是'data'等价。它更高效一些('数据'总是会产生一个额外的thunk间接层)。 – leftaroundabout