数据构造函数限制

时间:2016-08-29 22:10:57

标签: haskell

我有这样的数据结构:

data IfTree = If Expr Statement IfTree | Else Statement | EndIf

data Statement = IfStatement IfTree

想要的是不可能做任何这些组合:

IfStatement $ Else ...
IfStatement $ EndIf

IfStatement应该只能使用If

我知道我可以隐藏数据构造函数,只暴露在幕后组成它们的函数,但我想在数据类型中限制它。

更新

我试图做的是笨重的。由于出色的答案和评论,给出了一个更好的处理方法:

data Statement = If Expr Statement (Maybe Statement) | ...

甚至:

data Stat = IfStat Expr Stat | IfElseStat Expr Stat Stat | …

2 个答案:

答案 0 :(得分:4)

这将是传统的做法:

data Stat = IfStat Expr Stat (Maybe Stat) | BarStat | BazStat | …
data Expr = FooExpr | …

-- if (foo) bar;
IfStat FooExpr BarStat Nothing

-- if (foo) bar; else baz;
IfStat FooExpr BarStat (Just BazStat)

这个想法是将语言的语法编码为数据类型,或者至少是重要的位。 ElseEndIfIf之外没有意义,因此您实际上并不需要代表它们。

您可以将Maybe内联到语句数据类型中:

data Stat = IfStat Expr Stat | IfElseStat Expr Stat Stat | …

或者,如果它对您的语言有意义,您可以为空语句添加表示法:

data Stat = IfStat Expr Stat Stat | EmptyStat | …

-- if (foo) bar;
-- if (foo) bar; else;
IfStat FooExpr BarStat EmptyStat

-- if (foo) bar; else baz;
IfStat FooExpr BarStat BazStat

但是,如果您想在以后进行精确的漂亮打印,那么将这样的事情标准化可能会有问题。

可以类似地处理块语句:

data Stat = … | BlockStat [Stat] | …

-- if (foo) { bar; baz; }
IfStat FooExpr (BlockStat [BarStat, BazStat]) EmptyStat

答案 1 :(得分:2)

问题是If 不是只是Else。你应该定义像

这样的东西
data If = IfNoElse Expr Statement | IfElse Expr Statement Statement
data Statement = If If | While | ...
相关问题