2015-10-17 214 views
2

我是Haskell的初學者,正在解析和構建AST。我想知道如何定義類型如下:使一種類型成爲一種類型或另一種類型

A Value可以是IdentifierLiteral。現在,我只是有一種Value有兩個構造函數(取標識符的名稱和字符串常量的值分別爲):

data Value = Id String 
      | Lit String 

不過,後來想創建一個表示在一個分配的類型AST,所以我需要像

data Assignment = Asgn Value Value 

但顯然,我總是想一個Assignment的第一部分,始終是一個Identifier!所以我想我應該讓IdentifierLiteral不同的類型,以便更好地辨別事情:

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和讓我不知道是否有更好的解決辦法?

+2

你可能想看看[GADTs](https://en.wikibooks.org/wiki/Haskell/GADT)。既然'Id'和'Lit'現在都是基於'String'的,現在你可能想用一些額外的參數來區分這兩種類型(可能是一個幻象類型變量)。 –

+4

我不認爲數據值= ValueId標識符| ValueLit Literal'不夠好看。你不喜歡它什麼? - 順便提一下,注意通常我們更喜歡編寫'newtype Identifier = Id String',而不是'data'等價。它更高效一些('數據'總是會產生一個額外的thunk間接層)。 – leftaroundabout

回答

0

我首先嚐試重構我的類型,以便能夠使用GADT來完成它,但最終,更簡單的解決方案就是使用leftroundabout的建議。無論如何,我想這不是「不雅」。

相關問題