2017-04-13 78 views
1

我試圖爲一個字符串列表創建一個真值表。 說,我有一個列表["a","b"],並作爲輸出,我想 ​​Haskell中自定義數據類型的代碼

每個真值表的情況下被定義爲

data TableRow = [(String,Bool)] 

自定義數據類型有沒有這樣做的任何更簡單的方法這個?到現在爲止我一直在做這個


genRow :: [String] -> [TableRow] 
genRow [] = [] 
genRow (x:xs) = ((makeRow x True) : genRow xs) ++ 
      ((makeRow x False) : genRow xs) 

很顯然,這並不完全給我我所期望的。請注意,makeRow僅需要StringBool並返回TableRow

有沒有更乾淨的方法來做到這一點?由於

+0

是什麼'makeRow'嗎? –

+0

你是說你想要笛卡爾產品兩個列表?你知道列表解析嗎? – gspr

+0

'data TableRow = [(String,Bool)]'無效。你需要一個數據構造函數的名字。 –

回答

1

的問題與你的程序是genRow :: [String] -> [TableRow]產生TableRow元素的列表,你可以不使用利弊(:)構造上(String,Bool)TableRow因爲TableRow[[(String,Bool)]]

但是,您可以輕鬆地使用列表理解爲:因此

genRow :: [String] -> [[(String,Bool)]] 
genRow [] = [[]] 
genRow (x:xs) = [(x,b):ti | b <- [True,False], ti <- ts] where ts = genRow xs

第一條語句應該生成一個列表一個元素:在空列表[](而不是空列表作爲結果)。此外,我們使用列表理解:我們遍歷的兩個TrueFalseb,並且對於每個這樣的值,我們遍歷可能的值作爲尾部ts並且將(x,b)加到每個可能的尾部。

這給:

*Main> genRow ["A","B","C"] 
[[("A",True),("B",True),("C",True)], 
[("A",True),("B",True),("C",False)], 
[("A",True),("B",False),("C",True)], 
[("A",True),("B",False),("C",False)], 
[("A",False),("B",True),("C",True)], 
[("A",False),("B",True),("C",False)], 
[("A",False),("B",False),("C",True)], 
[("A",False),("B",False),("C",False)]] 
*Main> genRow ["Foo","Bar"] 
[[("Foo",True),("Bar",True)], 
[("Foo",True),("Bar",False)], 
[("Foo",False),("Bar",True)], 
[("Foo",False),("Bar",False)]] 

(新線增加了可讀性)

+0

哇,這很有道理。非常感謝。我不太清楚列表解析,並且不知道這個特定的語法。只是爲了澄清, 'genRow(x:xs)= [(x,b):ti | b < - [True,False],ti < - ts] 其中ts = genRow xs' 這是否工作,因爲它在每種情況下都爲True和False創建了單獨的列表? –

+0

你對一個單獨的列表有什麼意義? –