How to write an expression over a data type and print it out in haskell? -
i having write look build poly representation of polynomial x^3 + x + 1.
my algebraic info type poly, wrote is:
data poly = lit integer | var | add together poly poly | mul poly poly
the look can think of this, how can able print out result using print()?:
expr::poly->poly expr = add together (lit 1) $ add together (var) $ mul (var) $ mul var var
also, i'd write function this:
showpoly::poly->string showpoly (lit x) = show x showpoly (var) = "x" showpoly (add x y) = (show x) ++ " + " ++ (show y) showpoly (mul x y) = (show x) ++ "*" ++ (show y)
to enable passing of poly look , converting string. however, above work tells me have no instance (show poly), not sure mean.
first of all, expr
has wrong type. expr :: poly
correct. inquire ghci type:
in order utilize print
or similar function, type needs instance of show
, since
print :: show => -> io ()
one way accomplish derive show
instance automatically:
data poly = .... deriving (show)
however, won't lead desired result "x^3 + x + 1"
. need write show
instance yourself, example:
instance show poly show (add x y) = "(" ++ show x ++ ") * (" ++ show y ++ ") show (mul x y) = "(" ++ show x ++ ") * (" ++ show y ++ ") show (lit x) = show x show (var) = "x"
note still isn't you're looking for:
> show expr "(1) + ((x) + ((x) * ((x) * (x))))"however, info should enable create own instance.
another way solve problem implement showsprec
method of show
typeclass. function threads through precedence can take when apply parentheses, allowing print out look looks more 1 + x + x * x * x
instead of simple illustration using show
above. type of showsprec
little wonky, though, looks like
showsprec :: show => int -> -> shows
where
type shows = string -> string
the shows
type encoding diff list, allows more efficient construction of strings through function composition rather simple concatenation. poly
type, want implement this:
instance show poly showsprec d poly = case poly of lit -> shows var -> showstring "x" add together l r -> showparen (d > add_prec) $ showsprec add_prec l . showstring " + " . showsprec add_prec r mul l r -> showparen (d > mul_prec) $ showsprec mul_prec l . showstring " * " . showsprec mul_prec r -- infixl 6 + add_prec = 6 -- infixl 7 * mul_prec = 7
the d
parameter represents precedence. each phone call check if precedence greater of each operator, , if adds parentheses around look (showparen
conditionally puts parentheses around shows
), , builds left , right trees of look right precedence. precedences of 6
, 7
come asking ghci :i (+)
, :i (*)
, show fixity (precedence) of each operator respectively.
with instance can utilize write readable instances well:
instance num poly (+) = add together (*) = mul negate = mul (lit (-1)) frominteger = lit abs = undefined signum = undefined
keep in mind isn't exclusively behaved due undefined
s, allows write code like
x :: poly x = var expr1 :: poly expr1 = 1 + x + x * x * x expr2 :: poly expr2 = 2 * (x + 3 * x) expr3 :: poly expr3 = (4 + x) * (4 * (x + 2) * x + x * (x + x + 4))
and test:
> :l poly.hs > expr1 1 + x + x * x * x > expr2 2 * (x + 3 * x) > expr3 (4 * x) * (4 * (x + 2) * x + x * (x + x + 4))
which identical how defined in source code.
haskell
No comments:
Post a Comment