2016-08-29 49 views
1

我有數據結構,例如:數據構造限制

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 | …

回答

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

這回應了@DanielWagner上面的評論。但是你首先將答案正式化,所以我會將你的答案標記爲正確的。感謝您的優秀建議傢伙! – kurzweil4

+0

花了一些時間看這個之後,我想我找到了最優雅的IfStat/IfElseStat。 – kurzweil4

2

的問題是,一個If只是一個Else。你應該這樣定義

data If = IfNoElse Expr Statement | IfElse Expr Statement Statement 
data Statement = If If | While | ... 
+0

如果(COND){}否則如果{}否則{} ='如果ES(如果E」 s'的(否則S ''))' – kurzweil4

+0

如果(cond){} ='如果es EndIf' – kurzweil4

+0

@ kurzweil4當然可以。如果(cond){s}否則如果(cond'){s'} else {s''}'變成If IfElse cond s If IfElse cond's s'')))'。 –