Reputation: 101
I have the following data types
data Prop =
Var Name
| Neg Prop
| Conj Prop Prop
| Disy Prop Prop
| Impl Prop Prop
| Syss Prop Prop deriving Show -- if and only if
-- And the following
type Name = String
type State = (Name, Bool) -- The state of a proposition, Example ("P", True), ("Q", True)
type States = [State] -- A list of states, [("P", True), ("Q", False), ...]
type Row = (States, Bool) -- A row of the table. ([("P", True), ("Q", False), ...], True)
type Table = [Row]
The case is that I want to generate all the possible states of a proposition
P, Q, R
1 1 1
1 1 0
1 0 1
...
To do this, I create auxiliary functions to gradually build the states
-- Get all the atoms of a proposition
varList :: Prop -> [Name]
varList (Var p) = [p]
varList (Neg p) = varList p
varList (Conj p q) = varList p ++ varList q
varList (Disy p q) = varList p ++ varList q
varList (Impl p q) = varList p ++ varList q
varList (Syss p q) = varList p ++ varList q
--Power set to get all values
conjPoten :: Eq a => [a] -> [[a]]
conjPoten [] = [[]]
conjPoten (x:xs) = map (x: ) pt `union` pt
where
pt = conjPoten xs
-- Give value to a proposition, "P" -> True, "" -> False
giveValue:: Name -> Bool
giveValue p = p /= []
-- Generate a State, "P" -> ("P",True), "" -> ("",False)
generateState :: Name -> State
generateState p = (p , daValor p)
-- The function that I want
generateStates:: [Name] -> States
generateStates p = [(a,True) | a <-p]
This, of course, is a test to verify that "it works", because if generateStates ["P","Q", "R"] = [("P",True),("Q",True),("R",True)]
I did this thinking that in the power set we are going to have cases like ["P","Q","R"] and ["P","Q"], that is, there is not going to be "R". So the intention is that ["P","Q","R"] gives us [("Q",True),("P",True),("R",True)] and ["P","Q"] gives us [("Q",True),("P",True),("R",False)]
But from here I have two questions The first is, that I have to modify the second element of the tuple, so what I came up with was
generateStates :: [Name] -> States
generateStates p = [ (a, b) | a<- p, a<- giveValue p]
The main error that the prelude marks me is: Couldn't match type ‘[Char]’ with ‘Char’
Which I understand, because p is a list and giveValue works with a Name, not with a list of Names
I tried to do it like
generateStates :: [Name] -> States
generateStates [p] = [ (p, b) | a<- giveValue p]
But that tells me: Couldn't match expected type ‘[Bool]’ with actual type ‘Bool’ Which, now I don't understand, plus it tells me there aren't enough patterns
The other question is that, having
generateStates :: [Name] -> States
generateStates p = [ (a, True) | a<-p]
and try it with generateStates ["P","Q"] would only give me [("Q",True),("P",True)] But we have P, Q and R, so I'm missing the ("R", False) But since it is in the arguments that we pass, it cannot add it to the list
Thanks!
Upvotes: 2
Views: 307
Reputation: 143
To change the tuple, you really create a new one, as they are not mutable. You could create a function using pattern matching. The below function works on pairs (tuples with two elements).
modTuple (firstValue, secondValue) updatedValue = (firstValue, updatedValue)
Alternatively you could access the members of the tuple with the built-in fst
and snd
to access the first and second elements, and create a new tuple.
You can use pattern matching to access individual elements of a list, and build up States recursively. I.e.
generateStates [] = []
generateStates (p:ps) = (p, giveValue p):(generateStates ps)
Upvotes: 1