3

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.

hugomg
  • 68,213
  • 24
  • 160
  • 246
bartekmp
  • 403
  • 3
  • 9
  • 21
  • You may also like [this question with a very similar goal](http://stackoverflow.com/q/20406722/791604). – Daniel Wagner Jan 23 '14 at 18:20
  • Note, by the way, that you can write infix constructors if they begin with a `:`, so you could have `Formula :&: Formula`, `Formula :|: Formula`, and `Formula :=> Formula instead of `C`, `A`, and `I`. (You also may want fixity declarations then – perhaps `infixr 3 :&&:`, `infixr 2 :|:`, and `infixr 4 :=>`.) – Antal Spector-Zabusky Jan 24 '14 at 06:58
  • Thank you @AntalS-Z, that's pretty handy, but C, A and I are required, because are generated by other program. – bartekmp Jan 24 '14 at 12:24

2 Answers2

4

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.

hugomg
  • 68,213
  • 24
  • 160
  • 246
2

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))"
Stephen Diehl
  • 8,271
  • 5
  • 38
  • 56