Haskell pattern matching implicit type

Viewed 75

I'm new to Haskell, and i'm trying to make something with pattern matching. I don't even know if it's possible in that way. I have a data Fml :

    data Fml a = And (Fml a) (Fml a)
    | NAnd (Fml a) (Fml a)
    | Or (Fml a) (Fml a)
    | NOr (Fml a) (Fml a)
    | XOr (Fml a) (Fml a)
    | XNOr (Fml a) (Fml a)
    | Imply (Fml a) (Fml a)
    | Equiv (Fml a) (Fml a)
    | Not (Fml a)
    | Final (Var.Var a)
    deriving (Show)

Var is just a value (example : 1) I'm trying to make an easy function to merge all the Var in one Array. I've done this :

getVar :: (Eq a) => Fml a -> [Fml a]
getVar (And p q) = getVar p ++ getVar q
getVar (NAnd p q) = getVar p ++ getVar q
getVar (Or p q) = getVar p ++ getVar q
getVar (NOr p q) = getVar p ++ getVar q
getVar (XOr p q) = getVar p ++ getVar q
getVar (XNOr p q) = getVar p ++ getVar q
getVar (Imply p q) = getVar p ++ getVar q
getVar (Equiv p q) = getVar p ++ getVar q
getVar (Not p) = getVar p
getVar x = [x]

But i'm not satisfied because 8 of thoose cases are doing the same thing. I would like to know if it's possible to do something like this

getVar (_ p q) = getVar p ++ getVar q
1 Answers

You can define a type for the operator:

data Op2 = And | NAnd | Or | NOr | Xor | XNor | Imply | Equiv

and then define a data constructor that takes an operator and two parameters:

data Fml a
    = Fml2 Op2 (Fml a) (Fml a)
    | Not (Fml a)
    | Final (Var.Var a)
    deriving (Show)

Then your function thus looks like:

getVar :: Eq a => Fml a -> [Var.Var a]
getVar (Fml2 _ p q) = getVar p ++ getVar q
getVar (Not p) = getVar p
getVar (Final v) = [v]

I think the output type should be a list of Var.Vars, and not a Fml a, since your function hints that it is looking for a list of variables.

Related