Reputation: 171
I was trying to make a truth table for a list of strings.
Say, I have a list ["a","b"]
and as an output, I want
[[("a",True),("b",True)],
[("a",True),("b",False)],
[("a",False),("b",True)],
[("a",False),("b",False)]]
Each of those instances in the truth table are a custom data type defined as
data TableRow = [(String,Bool)]
Is there any easier way of doing this? Until now I have been doing this
genRow :: [String] -> [TableRow]
genRow [] = []
genRow (x:xs) = ((makeRow x True) : genRow xs) ++
((makeRow x False) : genRow xs)
Quite obviously, this does not quite give me what I expect. Note that makeRow
just takes in a String
and a Bool
and returns a TableRow
.
Is there any cleaner way of doing this? Thanks
Upvotes: 1
Views: 442
Reputation: 477437
The problem with your program is that genRow :: [String] -> [TableRow]
generates a list of TableRow
elements, and you cannot use the cons (:)
constructor on a (String,Bool)
and TableRow
since TableRow
is [[(String,Bool)]]
.
You can however easily use list comprehension for that:
genRow :: [String] -> [[(String,Bool)]]
genRow [] = [[]]
genRow (x:xs) = [(x,b):ti | b <- [True,False], ti <- ts]
where ts = genRow xs
The first statement should thus generate a list with one element: the empty list []
(not the empty list as result). Furthermore we use list comprehension: we iterate over the two Bool
s True
and False
for b
and for each such value, we iterate over the possible values as tails ts
and prepend the (x,b)
to each of the possible tails.
This gives:
*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)]]
(new lines added for readability)
Upvotes: 1