2011-03-22 57 views
0

我創建了一個數據組:哈斯克爾:自定義數據,使用功能

data Cars = vw | audi | ford 
data Engine = TDI | TSI 

我想在一個函數/列表解析使用這些。要顯示的組合我有這樣的:

[(x,y) | x <- Cars , y <- Engine] 

但I'mm一點點失去了如何在一個函數中使用data

我得到這個錯誤:

Not in scope: data constructor `Cars' 
+0

請注意,類型構造函數和類型名稱的名稱都必須以大寫字母開頭。 – fuz 2011-03-22 18:47:58

回答

3

使用這些列表是你想要的嗎?

$cat t.hs 
data Cars = Vw | Audi | Ford 
     deriving (Enum, Show) 
data Engine = TDI | TSI 
     deriving (Enum, Show) 


main = print [(x,y) | x <- [Vw .. Ford] , y <- [TDI .. TSI]] 


$ghc t.hs 

$./a.out 
[(Vw,TDI),(Vw,TSI),(Audi,TDI),(Audi,TSI),(Ford,TDI),(Ford,TSI)] 
+1

你會說出這裏發生了什麼? – luqui 2011-03-22 22:08:16

11

CarsEngine的類型,僅此而已,特別是沒有構造函數列表。要獲得一個類型的所有構造函數的集合,使其成爲Enum的一個實例,也許Bounded(您可以derive兩者,Bounded不是必需的,但它很好,因爲它不允許對起始值進行硬編碼)。見例如this question(特別是,this answer)。複製和調整的代碼(也,我固定構建函數的外殼,並更名Cars,因爲它是複數而不是非常具體):

data CarManufacturer = VW | Audi | Ford deriving (Bounded, Enum) 
data Engine = TDI | TSI deriving (Bounded, Enum) 

allValues :: (Bounded a, Enum a) => [a] 
allValues = [minBound..] 

allEngines = allValues :: [Engine] 
allCars = allValues :: [CarManufacturer] 

carsWithEngines = [(car, engine) | car <- allCars, engine <- allEngines] 
+1

我比我的方法更喜歡這個;但如果將'deriving'子句添加到您的代碼中,那將會很好。 – 2011-03-22 16:24:24

+0

@John:修好,謝謝。 – delnan 2011-03-22 16:25:53

+0

+1我喜歡通用的'allValues'函數的想法,我從來沒有想過。我知道很多情況下,這可以節省我的程序中的一些代碼。 – 2011-03-23 10:07:47

1

可惜你不能訪問的數據類型的構造函數這種方式。首先,所有的數據構造需要大寫,所以改成這樣:

data Cars = VW | Audi | Ford deriving Show 
data Engine = TDI | TSI  deriving Show 

-- create explicit lists of the constructors 
carTypes :: [Cars] 
carTypes = [VW, Audi, Ford] 

engineTypes :: [Engine] 
engineTypes = [TDI, TSI] 

現在你可以在列表解析

> let ll = [(x,y) | x <- carTypes, y <- engineTypes] 
> show ll 
> [(VW,TDI),(VW,TSI), (Audi,TDI),(Audi,TSI),(Ford,TDI),(Ford,TSI)] 
> :type ll 
> ll :: [(Cars,Engine)]