Automatic parentheses in `Show` instances - haskell

ghci> show (Left 3)
"Left 3"
ghci> show (Just 0)
"Just 0"
ghci> show (Just (Left 3))
"Just (Left 3)"
How does Haskell automatically put parentheses around nested constructor arguments?

showsPrec :: Int -> a -> ShowS is the function used internally by show to consistently put parentheses around a term.
The Int parameter indicate the precedence of the outer context. If the precedence of the current constructor is greater than the precedence of the context, showParen :: Bool -> ShowS -> ShowS puts parentheses around the constructor. Here an example for a very basic AST :
data Exp = Exp :+: Exp
| Exp :*: Exp
-- The precedence of operators in haskell should match with the AST shown
infixl 6 :+:
infixl 7 :*:
mul_prec, add_prec :: Int
mul_prec = 7
add_prec = 6
instance Show Exp where
showsPrec p (x :+: y) = showParen (p > add_prec) $ showsPrec (add_prec+1) x
. showString " :+: "
. showsPrec (add_prec+1) y
showsPrec p (x :*: y) = showParen (p > mul_prec) $ showsPrec (mul_prec+1) x
. showString " :*: "
. showsPrec (mul_prec+1) y
show t = showsPrec 0 t "" -- Default definition
showsPrec, showString, showParen, etc, act on difference lists (ShowS = String -> String), where the argument is a string appended to the result. Concatenation is done by composition, and conversion to String by application with an empty string.
The show implementation use showsPrec with the lowest precedence, the expression to print, and finally, the end of the string [].

Related

Haskell - Pattern matching with data types

I have a data type and function like this:
data Expr = Num Int | Add Expr Expr | Mult Expr Expr | Neg Expr | If Expr Expr Expr deriving (Show, Read)
prettyPrint :: Expr -> IO ()
prettyPrint expr = prettyPrint' expr 0
prettyPrint' :: Expr -> Int -> IO ()
prettyPrint' (Num x) i = putStrLn $ concat (replicate i " ") ++ "Num " ++ show x
prettyPrint' (Add x y) i = do
putStrLn $ concat (replicate i " ") ++ "Add"
prettyPrint' x (i+1)
prettyPrint' y (i+1)
prettyPrint' (Mult x y) i = do
putStrLn $ concat (replicate i " ") ++ "Mult"
prettyPrint' x (i+1)
prettyPrint' y (i+1)
prettyPrint' (Neg x) i = do
putStrLn $ concat (replicate i " ") ++ "Neg"
prettyPrint' x (i+1)
prettyPrint' (If x y z) i = do
putStrLn $ concat (replicate i " ") ++ "If"
prettyPrint' x (i+1)
prettyPrint' y (i+1)
prettyPrint' z (i+1)
In the function I am using pattern matching. The problem is that their is a lot of reuse of code. For example, the case for Mult and Add is basically the same code. Same goes for Num and Neg. Is there a way to write this based on how many variables the expression have? Like one for Num and Neg, since they have only one variable. One case for Mult and Add, since they have two variables. And a last case for If, since that expression have three variables.
NOTE:
I landed on this answer, I think it's a better solution than I started with:
prettyPrint :: Expr -> IO ()
prettyPrint expr = putStrLn (prettyPrint' 1 expr)
prettyPrint' :: Int -> Expr -> String
prettyPrint' i (Num x) = "Num " ++ show x
prettyPrint' i expr =
let indent x = concat (replicate i " ") ++ x
(op, args) = case expr of
Add x y -> ("Add", [x,y])
Mult x y -> ("Mult", [x,y])
Neg x -> ("Neg", [x])
If x y z -> ("If", [x,y,z])
in intercalate "\n" (op : map (indent . prettyPrint' (i + 1)) args)
First, I would stay out of the IO monad for as long as possible. Have prettyPrint' return a string to be printed.
prettyPrint :: Expr -> IO ()
prettyPrint = putStrLn . prettyPrint'
Now, the only job of prettyPrint' is to create a (possibly multiline) string to be printed. For numbers, that's easy: just use the show instance.
prettyPrint' :: Expr -> String
prettyPrint' e#(Num _) = show e
-- or, ignoring the Show instance for Expr altogether
-- prettyPrint' (Num x) = "Num " ++ show x
For the rest, there is a pattern:
Identify the constructor
Identify its arguments
Join the constructor name and its pretty-printed arguments with newlines. Each argument will be indented one level relative to its operator; the recursion will take care of multiple levels of indentation.
That will look like
prettyPrint' expr = let indent x = " " ++ x
(op, args) = case expr of
Add x y -> ("Add", [x,y])
Mult x y -> ("Mult", [x,y])
Neg x -> ("Neg", [x])
If x y z -> ("If", [x,y,z])
in intercalate "\n" (op : map (indent . prettyPrint') args)
As an example, consider what prettyPrint' will do with the expression Add (Num 3) (Num 5). First, it sets op to "Add" and args to [Num 3, Num 5]. Next, it maps indent . prettyPrint' over the argument list, to get [" Num 3", " Num 5"]. Putting the operator on the front of the list yields ["Add", " Num 3", " Num 3"], then joining them with intercalate produces "Add\n Num 3\n Num 5".
The only remaining boilerplate is in the case expression. I think it's possible to eliminate that, but it requires a level of generic programming I'm not familiar with. I'm sure someone else could probably run with my answer to fix that.
In general, when addressing duplication in code, it pays to keep the rule of three in mind. Two occurrences of a block of code isn't necessarily a problem.
That said, Haskell is a (very) strongly-typed language, so you generally can't pattern-match on arity like you can in, say, Erlang or Clojure.
If you really want to abstract away the recursion part of a recursive data structure, you can define the catamorphism for it. People often also call this a fold, so let's keep that slightly more friendly name:
data Expr =
Num Int | Add Expr Expr | Mult Expr Expr | Neg Expr | If Bool Expr Expr deriving (Show, Read)
foldExpr ::
(Int -> a) -> (a -> a -> a) -> (a -> a -> a) -> (a -> a) -> (Bool -> a -> a -> a) -> Expr -> a
foldExpr num _ _ _ _ (Num x) = num x
foldExpr num add mul neg iff (Add x y) =
add (foldExpr num add mul neg iff x) (foldExpr num add mul neg iff y)
foldExpr num add mul neg iff (Mult x y) =
mul (foldExpr num add mul neg iff x) (foldExpr num add mul neg iff y)
foldExpr num add mul neg iff (Neg x) = neg (foldExpr num add mul neg iff x)
foldExpr num add mul neg iff (If b x y) =
iff b (foldExpr num add mul neg iff x) (foldExpr num add mul neg iff y)
This is an entirely generic function that enables you turn turn any Expr value into any value of the type a, without worrying about reimplementing recursion every time. You just have to supply functions that deal with each of the cases.
You can, for example, easily write an evaluator:
evaluate :: Expr -> Int
evaluate = foldExpr id (+) (*) negate (\p x y -> if p then x else y)
(Notice, BTW, that I changed the definition of If, because I couldn't see how the OP definition would work.)
You can also write a function to turn an Expr value into a string, although this one is just a sketch; it needs indentation or bracket logic to work correctly:
prettyPrint :: Expr -> String
prettyPrint =
foldExpr
show -- Num
(\x y -> x ++ "+" ++ y) -- Add
(\x y -> x ++ "*" ++ y) -- Mult
(\x -> "(-" ++ x ++ ")") -- Neg
(\p x y -> "if " ++ show p ++ " then " ++ x ++ " else " ++ y) -- If
You can try it out in GHCi:
*Q53284410> evaluate (Num 42)
42
*Q53284410> evaluate (Add (Num 40) (Num 2))
42
*Q53284410> evaluate (Add (Mult (Num 4) (Num 10)) (Num 2))
42
*Q53284410> prettyPrint $ Num 42
"42"
*Q53284410> prettyPrint $ Mult (Num 6) (Num 7)
"6*7"
*Q53284410> prettyPrint $ Add (Mult (Num 2) (Num 3)) (Num 7)
"2*3+7"
Yes, just create a function to print list of Expr:
import Control.Monad (forM_)
printExprList::[Expr]->Int->String->IO ()
printExprList exprs i desc = do
putStrLn $ concat (replicate i " ") ++ desc
forM_ (zip exprs [i..]) $ \(e, j)-> prettyPrint' e (j+1)
and then call it to print:
prettyPrint' :: Expr -> Int -> IO ()
prettyPrint' (Add x y) i = printExprList [x, y] i "Add"
prettyPrint' (Mult x y) i = printExprList [x, y] i "Mult"
prettyPrint' (Neg x) i = printExprList [x] i "Neg"
prettyPrint' (If x y z) i = printExprList [x, y, z] i "If"
prettyPrint' (Num x) i = putStrLn $ concat (replicate i " ")
++ "Num " ++ show x

Trying to create a function that maps another function into a function list

compose :: [(u -> t)] -> ((u -> t) -> (u->y)) -> [(u->y)]
compose [] _ = []
compose l f = map f l
Im trying to create a function that receive a list of functions and maps another function over the elements of this lists.
Example:
compose [(+2),(+3)] (+1) = [(+3),(+4)]
thats the message the console shows me when i try to run this code
*Main> (compose [(+2)] (+1))
:77:2:
No instance for (Show (t0 -> t0)) arising from a use of `print'
In a stmt of an interactive GHCi command: print it
*Main>
There isn't a way to intelligently convert a function to a string, which is what the error message you see here is saying. There isn't a Show instance for functions, and you need a Show instance to see output in GHCi. When you create a function in Haskell the compiler turns it into low level commands, you don't have the original function definition preserved in metadata or anything. You wouldn't be able to see (+1) . (+2) become (+3), it just isn't how Haskell functions work.
Instead you could assign it to a name:
> let fs = compose [(+2)] (+1)
Then apply values to it
> map ($ 10) fs
[13]
If you want to be able to turn something like (+2) and (+1) into (+3), you'll need to create your own data type. This means that the functions you can represent are severely limited in what they can do unless you define very generic behavior. For simple functions on Ints, you could do
data ArithFunc
= Add Int
| Subtract Int
| Multiply Int
| ModBy Int
| Abs
| Negate
| Compose ArithFunc ArithFunc
deriving (Eq, Show)
Then you could write a custom compose operator:
toFunction :: ArithFunc -> (Int -> Int)
toFunction (Add x) = (+x)
toFunction (Subtract x) = subtract x
toFunction (Multiply x) = (*x)
toFunction (ModBy x) = (`mod` x)
toFunction Abs = abs
toFunction Negate = negate
toFunction (Compose f1 f2) = toFunction f1 . toFunction f2
infixr 9 #
(#) :: ArithFunc -> ArithFunc -> ArithFunc
f1 # f2 = simplify $ Compose f1 f2
infixr 0 $$
($$) :: ArithFunc -> Int -> Int
f $$ x = toFunction f x
simplify (Compose (Add x) (Add y)) = Add (x + y)
simplify (Compose (Add x) (Subtract y)) = Add (x - y)
-- Continue adding simplification rules as desired
compose :: [ArithFunc] -> (ArithFunc -> ArithFunc) -> [ArithFunc]
compose l f = map (simplify . f) l
Then you could write
> compose [Add 2] (Add 1)
[Add 3]
> map ($$ 10) $ compose [Add 2] (Add 1)
[13]
And this solution is of no where near complete, you would really need to define simplify in such a way that it continues to simplify nested Compose constructs until no change was made, there needs to be more rules for simplification, there are other operations that could be represented, resulting in a larger number of simplification rules needed, and more. All of this work above is just to do this sort of thing with a limited set of numeric computations on Ints only, imagine expanding this to work for all types in general. This is why Haskell chooses a simpler route of storing the function definition less literally, and why you therefore can't show a function.

Taking data and turning it into a string

Given the following code:
data Exprs = Const Double
| Var String --in math we often use char
| Sqrt Exprs --we can take sqrt of anything
| IntPow Exprs Int--the easy case of exponents
| Exp Exprs --e^expr
| Ln Exprs --logarithms
| Mult Exprs Exprs--multiplication
| Add Exprs Exprs
| Neg Exprs
deriving (Show, Eq, Ord)
x = Var "x"
y = Var "y"
z = Var "z"
-- to multiply x and y we type in "Mult x y"
example = Add (Const 7) ( Mult (Const 4) (Add (Sqrt x) (Exp y)))
How would I make a function that displays 7 + 4 * (sqrt(x)) + e^y from example?
What you want to implement here is the showsPrec function in the Show typeclass. This function takes an extra argument that indicates the precedence of the operation, allowing you to more easily achieve sane parentheses, and it also is more efficient since it uses what amounts to a diff list for building the string (more efficient concatenation). The function show defaults to \x -> showsPrec 0 x "", so when you call show it will work properly. An incomplete example for your case would be
data Exprs
= Const Double
| Var String --in math we often use char
| Sqrt Exprs --we can take sqrt of anything
| IntPow Exprs Int--the easy case of exponents
| Exp Exprs --e^expr
| Ln Exprs --logarithms
| Mult Exprs Exprs--multiplication
| Add Exprs Exprs
| Neg Exprs
deriving (Eq, Ord)
instance Show Exprs where
showsPrec n (Const x) = showParen (n > 10) $ showsPrec 11 x
showsPrec n (Var var) = showParen (n > 10) $ showString var
showsPrec n (Add l r) = showParen (n > 6) $ showsPrec 7 l . showString "+" . showsPrec 7 r
showsPrec n (Mult l r) = showParen (n > 7) $ showsPrec 8 l . showString "*" . showsPrec 8 r
showsPrec n (Sqrt e) = showParen (n > 10) $ showString "sqrt(" . shows e . showString ")"
I'll leave it to you to implement the other constructors (and test it heavily to ensure there are no mistakes, I do not guarantee that this is 100% correct), but you should have a pretty good start here. You may want to experiment with :i (*), :i (+), and :i (**) to figure out where the precedences I've used have come from.
As I posted in a comment to #ThreeFx's answer, I think it's bad practice to use the Show typeclass for pretty-printing or other general string munging. The documentation for Show notes that, for derived instances, "The result of show is a syntactically correct Haskell expression" made of constructors, constants, etc. That's not a rule per se, but it's a very helpful invariant. When you evaluate an expression in ghci, for instance, you expect to get a result that you can then copy-paste and reuse in code. Using Show to perform the operation you want breaks that expectation.
Rather, I think you should expose a function--not show--that you can properly document, etc., and that doesn't violate the implicit contract on Show instances. #Bakuriu suggested as much in a comment.
The implementation of that function can be almost identical to the solutions #ThreeFx and #bheklilr proposed... just without the instance part. Here's my rendition of #bheklilr's version:
data Exprs
= Const Double
| Var String --in math we often use char
| Sqrt Exprs --we can take sqrt of anything
| IntPow Exprs Int--the easy case of exponents
| Exp Exprs --e^expr
| Ln Exprs --logarithms
| Mult Exprs Exprs--multiplication
| Add Exprs Exprs
| Neg Exprs
deriving (Eq, Ord, Show, Read)
prettyPrint :: Exprs -> String
prettyPrint e = go 0 e ""
where
go n (Const x) = showParen (n > 10) $ showsPrec 11 x
go n (Var var) = showParen (n > 10) $ showString var
go n (Add l r) = showParen (n > 6) $ go 7 l . showString "+" . go 7 r
go n (Mult l r) = showParen (n > 7) $ go 8 l . showString "*" . go 8 r
go n (Sqrt e) = showParen (n > 10) $ showString "sqrt(" . go n e . showString ")"
Note that all I've done is mechanically rewrite showsPrec as go and wrap it in a convenience function.
Now Read and Show work dandy, and we can get nice pretty-printing:
*SO26169469> Add (Const 7) ( Mult (Const 4) (Add (Sqrt (Var "x")) (Const 3)))
Add (Const 7.0) (Mult (Const 4.0) (Add (Sqrt (Var "x")) (Const 3.0)))
*SO26169469> show it
"Add (Const 7.0) (Mult (Const 4.0) (Add (Sqrt (Var \"x\")) (Const 3.0)))"
*SO26169469> read it :: Exprs
Add (Const 7.0) (Mult (Const 4.0) (Add (Sqrt (Var "x")) (Const 3.0)))
*SO26169469> prettyPrint it
"7.0+4.0*(sqrt(x)+3.0)"
P.S. I don't claim to be any authority; I'm sure many people would support using Show as the other contributors suggest.
Careful: Bad practice ahead!
As Christian pointed out in his comment, show should yield a syntactically valid Haskell construct, which is why overriding show is not considered good practice. You should hava a look at bheklilr's answer or Bakuriu's comments on the question.
Nevertheless, one possible way is to implement the Show instance manually for every constructor:
instance Show Exprs where
show (Const d) = show d
show (Var v) = v
show (Sqrt ex) = "(sqrt(" ++ show ex ++ "))"
..
show (Add e1 e2) = show e1 ++ " + " ++ show e2
..
Sample output:
*Main> Sqrt (Var "x")
(sqrt(x))
*Main> Add (Sqrt (Const 4)) (Var "x")
(sqrt(4.0)) + x

Printing an AST with variable names

I am trying to implement an EDSL in Haskell. I would like to pretty print the AST with the variable names that are bound (if I can't get the real names then some generated names would do).
This is how far I have got with a simple example:
import Control.Monad.State
data Free f a = Roll (f (Free f a))
| Pure a
instance Functor f => Monad (Free f) where
return = Pure
(Pure a) >>= f = f a
(Roll f) >>= g = Roll $ fmap (>>= g) f
data Expr a = I a
| Plus (Expr a) (Expr a)
deriving (Show)
data StackProgram a next = Pop (a -> next)
| Push a next
instance Functor (StackProgram a) where
fmap f (Pop k) = Pop (f.k)
fmap f (Push i x) = Push i (f x)
liftF :: Functor f => f a -> Free f a
liftF l = Roll $ fmap return l
push :: a -> Free (StackProgram a) ()
push i = liftF $ Push i ()
pop :: Free (StackProgram a) a
pop = liftF $ Pop id
prog3 :: Free (StackProgram (Expr Int)) (Expr Int)
prog3 = do
push (I 3)
push (I 4)
a <- pop
b <- pop
return (Plus a b)
showSP' :: (Show a, Show b) => Free (StackProgram a) b -> [a] -> State Int String
showSP' (Pure a) _ = return $ "return " ++ show a
showSP' (Roll (Pop f)) (a:stack) = do
i <- get
put (i+1)
rest <- showSP' (f a) stack
return $ "var" ++ show i ++ " <- pop " ++ show (a:stack) ++ "\n" ++ rest
showSP' (Roll (Push i n)) stack = do
rest <- showSP' n (i:stack)
return $ "push " ++ show i ++ " " ++ show stack ++ "\n" ++ rest
showSP :: (Show a, Show b) => Free (StackProgram a) b -> [a] -> String
showSP prg stk = fst $ runState (showSP' prg stk) 0
Running this gives:
*Main> putStrLn $ showSP prog3 []
push I 3 []
push I 4 [I 3]
var0 <- pop [I 4,I 3]
var1 <- pop [I 3]
return Plus (I 4) (I 3)
So what I want is to replace Plus (I 4) (I 3) with Plus var0 var1. I have thought about walking through the rest of the tree and replacing the bound variables with name-value tuples, but I am not 100% sure if/how that would work. I'd also prefer to keep the original variable names, but I can't think of an easy way of doing this. I would prefer to have a fairly light-weight syntax in haskell (kind of as above).
I would also appreciate pointers to material that teaches me how to best do these kinds of things. I have read a bit on free monads and GADTs, but I guess I am missing how to put it all together.
With the structure you have, you can't do this in "pure" Haskell code, because once your code is compiled, you can't distinguish (Plus a b) from (Plus (I 4) (I 3)) and keep "referential transparency" - the interchangeability of variables and their values.
However there are unsafe hacks - i.e. not guaranteed to work - that can let you do this kind of thing. They generally go under the name "observable sharing" and are based on getting access to the internals of how values are represented, using StableName. Essentially that gives you a pointer equality operation that allows you to distinguish between the reference to a and a new copy of the value (I 4).
One package that helps wrap up this functionality is data-reify.
The actual variable names used in your source will be irretrievably lost during compilation. In Paradise we use a preprocessor to translate foo <~ bar into foo <- withName "foo" $ bar before compilation, but it's hacky and it slows down builds quite a bit.
I figured this out based on #Gabriel Gonzales' linked answer. The basic idea is to introduce a new variable constructor in the Expr type and you assign these a unique id as you interpret the tree. That and cleaning up the code a bit gives:
import Control.Monad.Free
import Data.Map
newtype VInt = VInt Int
data Expr = IntL Int
| IntV VInt
| Plus Expr Expr
instance Show Expr where
show (IntL i) = show i
show (IntV (VInt i)) = "var" ++ show i
show (Plus e1 e2) = show e1 ++ " + " ++ show e2
data StackProgF next = Pop (VInt -> next)
| Push Expr next
instance Functor StackProgF where
fmap f (Pop k) = Pop (f.k)
fmap f (Push e x) = Push e (f x)
type StackProg = Free StackProgF
type Stack = [Expr]
push :: Expr -> StackProg ()
push e = liftF $ Push e ()
pop :: StackProg Expr
pop = liftF $ Pop IntV
prog3 :: StackProg Expr
prog3 = do
push (IntL 3)
push (IntL 4)
a <- pop
b <- pop
return (Plus a b)
showSP :: StackProg Expr -> String
showSP prg = go 0 prg []
where
go i (Pure a) _ = show a
go i (Free (Pop n)) (h:t) = "var" ++ show i ++ " <- pop " ++ show (h:t) ++ "\n" ++
go (i+1) (n (VInt i)) t
go i (Free (Pop _)) [] = "error: pop on empty stack\n"
go i (Free (Push e n)) stk = "push " ++ show e ++ ", " ++ show stk ++ "\n" ++ go i n (e:stk)
type Env = Map Int Expr
evalExpr :: Expr -> Env -> Int
evalExpr (IntL i) _ = i
evalExpr (IntV (VInt k)) env = evalExpr (env ! k) env
evalExpr (Plus e1 e2) env = evalExpr e1 env + evalExpr e2 env
evalSP :: StackProg Expr -> Int
evalSP prg = go 0 prg [] empty
where
go i (Free (Pop _)) [] env = error "pop on empty stack\n"
go i (Free (Pop n)) (h:t) env = go (i+1) (n (VInt i)) t (insert i h env)
go i (Free (Push e n)) stk env = go i n (e:stk) env
go i (Pure a) _stk env = evalExpr a env
Pretty printing and running:
*Main> putStrLn $ showSP prog3
push 3, []
push 4, [3]
var0 <- pop [4,3]
var1 <- pop [3]
var0 + var1
*Main> evalSP prog3
7

Error: "No instances for (x)..."

Exercise 14.16-17 in Thompson asks me to add the operations of multiplication and (integer) division to the type Expr, which represents a simple language for arithmetic, then define the functions show and eval (evaluates an expression of type Expr) for Expr.
My solution works for each arithmetic operation except division:
data Expr = L Int
| Expr :+ Expr
| Expr :- Expr
| Expr :* Expr
| Expr :/ Expr
instance Num Expr where
(L x) + (L y) = L (x + y)
(L x) - (L y) = L (x - y)
(L x) * (L y) = L (x * y)
instance Eq Expr where
(L x) == (L y) = x == y
instance Show Expr where
show (L n) = show n
show (e1 :+ e2) = "(" ++ show e1 ++ " + " ++ show e2 ++ ")"
show (e1 :- e2) = "(" ++ show e1 ++ " - " ++ show e2 ++ ")"
show (e1 :* e2) = "(" ++ show e1 ++ " * " ++ show e2 ++ ")"
show (e1 :/ e2) = "(" ++ show e1 ++ " / " ++ show e2 ++ ")"
eval :: Expr -> Expr
eval (L n) = L n
eval (e1 :+ e2) = eval e1 + eval e2
eval (e1 :- e2) = eval e1 - eval e2
eval (e1 :* e2) = eval e1 * eval e2
E.g.,
*Main> (L 6 :+ L 7) :- L 4
((6 + 7) - 4)
*Main> it :* L 9
(((6 + 7) - 4) * 9)
*Main> eval it
81
it :: Expr
However, I am running into problems when I try to implement division. I don't understand the error message I receive when I try to compile the following:
instance Integral Expr where
(L x) `div` (L y) = L (x `div` y)
eval (e1 :/ e2) = eval e1 `div` eval e2
This is the error:
Chapter 14.15-27.hs:19:9:
No instances for (Enum Expr, Real Expr)
arising from the superclasses of an instance declaration
at Chapter 14.15-27.hs:19:9-21
Possible fix:
add an instance declaration for (Enum Expr, Real Expr)
In the instance declaration for `Integral Expr'
In the first place, I have no idea why defining div for the data type Expr requires me to define an instance of Enum Expr or Real Expr.
Well, that's the way the Integral typeclass is defined. For information, you can e.g. just type :i Integral into GHCi.
You'll get
class (Real a, Enum a) => Integral a where ...
which means any type a that should be Integral has to be Real and Enum first. C'est la vie.
Note that maybe you've got your types messed up quite a bit. Take a look at
instance Num Expr where
(L x) + (L y) = L (x + y)
(L x) - (L y) = L (x - y)
(L x) * (L y) = L (x * y)
This just allows you to add Expressions if they wrap plain numbers. I'm pretty sure you don't want that.
You want to add arbitrary expressions and you already have a syntax for this. It's just
instance Num Expr where
(+) = (:+)
(-) = (:-)
-- ...
This allows you to write (L 1) + (L 2) with perfectly normal syntax. Likewise, eval should not just reduce expressions but yield a number, and therefore have the type eval :: Expr -> Integer. Division is simple for that matter
eval (a :/ b) = (eval a) `div` (eval b)
which is defined since you just divide numbers.

Resources