My goal is to be able to represent boolean expressions as strings, for example "True or False is True"
. In order to make it possible I first made some boolean predicates:
and' :: Bool -> Bool -> Bool
and' p q = p && q
or' :: Bool -> Bool -> Bool
or' p q = p || q
-- ... same for nor, nand, xor, imply and equivalent
equ' :: Bool -> Bool -> Bool
equ' p q = p == q
After that, I decided to make a function that maps functions to strings. I relied on the pattern matching feature of Haskell, but my trick didn't work.
-- representation function, a.k. "show" for functions
repr :: (Bool -> Bool -> Bool) -> [Char]
repr and' = "and"
repr or' = "or"
repr nand' = "nand"
repr nor' = "nor"
repr xor' = "xor'"
repr impl' = "implies"
repr equ' = "equivalent to"
repr other = error "No representation for the given predicate"
GHC thinks that function name is a parameter name and considers only the first definition as a general case. For the remaining lines, GHC raises a warning that the "pattern match is redundant". This is an example of running repr
function:
*LogicH99> repr equ'
"and"
Expected "equivalent to"
Is it possible to print a function in a fancy way in Haskell?
For functions in general, no there isn't. But for functions of type Bool -> Bool -> Bool
, there's so few possibilities that it's practical to just exhaustively enumerate all inputs, by doing something like this:
repr f = case (f False False, f False True, f True False, f True True) of
(False, False, False, True) -> "and"
(False, True, True, True) -> "or"
-- ...
(True, False, False, True) -> "equivalent to"
_ -> error "No representation for the given predicate"