bartekmp
bartekmp

Reputation: 413

Logic formula printing in Haskell

I am dealing with some weird problem. I want to write a Haskell program, which will print given logical formulae, i.e.

print (showFormula (I (N (Z 'p')) (A (C (Z 'p') (Z 'q')) (Z 'r'))))

(where I is implication, A - alternative, N - negation, C - conjunction and Z - character)

should print something like that:

"(~p => ((p & q) | r))"

So far, my code looks like that:

data Formula
    = Z Char
    | V Bool
    | N Formula
    | C Formula Formula
    | A Formula Formula
    | I Formula Formula
    | Join Formula Formula

showFormula :: Formula -> String
showFormula (Z c) = [c]
showFormula (Join a b) = (showFormula a) ++ (showFormula b)

showFormula (N a) = '~':(showFormula a)
showFormula (C a b) = "("++(showFormula a)++" & "++(showFormula b)++")"
showFormula (A a b) = "("++(showFormula a)++" | "++(showFormula b)++")"
showFormula (I a b) = "("++(showFormula a)++" => "++(showFormula b)++")"

It does print proper string but only when you input simple formula like (C (Z 'a') (Z 'b')) and it crashes with some expanded formulae. I know that the problem is passing a Formula parameter instead of String to showFormula function, but I have no idea how to change that. Please give me some advices how to fix that.

Upvotes: 3

Views: 273

Answers (2)

Stephen Diehl
Stephen Diehl

Reputation: 8439

Looks like you just missed the (V b) case in your pattern match.

data Formula
    = Z Char
    | V Bool
    | N Formula
    | C Formula Formula
    | A Formula Formula
    | I Formula Formula
    | Join Formula Formula

showFormula :: Formula -> String
showFormula (V b) = show b
showFormula (Z c) = [c]
showFormula (Join a b) = (showFormula a) ++ (showFormula b)

showFormula (N a) = '~':(showFormula a)
showFormula (C a b) = "("++(showFormula a)++" & "++(showFormula b)++")"
showFormula (A a b) = "("++(showFormula a)++" | "++(showFormula b)++")"
showFormula (I a b) = "("++(showFormula a)++" => "++(showFormula b)++")"

main :: IO ()
main = do
  print (showFormula (I (N (Z 'p')) (A (C (Z 'p') (Z 'q')) (Z 'r'))))
  -- "(~p => ((p & q) | r))"

Upvotes: 2

hugomg
hugomg

Reputation: 69984

If you compile your code with the -Wall flag it will show you the following warning:

fml.hs:4:1: Warning:
    Pattern match(es) are non-exhaustive
    In an equation for `showFormula': Patterns not matched: V _

You forgot to write the V case for showFormula so it will crash if it reaches that, similarly to how the head function crashes if you call it with an empty list.

Upvotes: 4

Related Questions