首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据构造器限制

数据构造器限制
EN

Stack Overflow用户
提问于 2016-08-29 22:10:56
回答 2查看 74关注 0票数 1

我有这样的数据结构:

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

data Statement = IfStatement IfTree

我们想要的是不可能做任何这样的组合:

代码语言:javascript
复制
IfStatement $ Else ...
IfStatement $ EndIf

一个IfStatement应该只能接受一个If

我知道我可以隐藏数据构造函数,并且只能在幕后公开组成它们的函数,但是我想在数据类型中限制这一点。

更新:

我想做的是笨重的。由于有了出色的答复和评论,提出了一种更好的处理这一问题的方法:

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

甚至:

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-29 23:59:25

这将是传统的做法:

代码语言:javascript
复制
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内联到语句数据类型中:

代码语言:javascript
复制
data Stat = IfStat Expr Stat | IfElseStat Expr Stat Stat | …

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

代码语言:javascript
复制
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

然而,如果你以后想要精确的漂亮印刷,像这样的事情正常化可能会有问题。

块语句也可以类似地处理:

代码语言:javascript
复制
data Stat = … | BlockStat [Stat] | …

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

Stack Overflow用户

发布于 2016-08-29 23:00:18

问题是,If不仅仅是Else。你应该定义如下

代码语言:javascript
复制
data If = IfNoElse Expr Statement | IfElse Expr Statement Statement
data Statement = If If | While | ...
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39215958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档