Again Haskellers & Haskellettes,
I still have the problem, that I don’t really know when to use (Class a) => a, Type or
Type a where Type is a “union type” as for example Val and ExprTree
Now i want to make my datatype ExprTree a bit more versatile by adding a few instances:
import Ratio
data Fun = Add|Sub|Mul|Div|Pow
deriving (Eq,Ord)
instance Show Fun where
show Add = "+"
show Sub = "-"
show Mul = "*"
show Div = "/"
show Pow = "^"
type Label = Rational
type Var = String
class Eval e where
eval :: (Num a) => e -> a -> a
data ExprTree a = Leaf {lab::Label, val::Val a}
| Node {lab::Label, fun::Fun, lBranch::ExprTree a, rBranch::ExprTree a}
deriving(Eq,Ord)
data Val a = Num a | Var String deriving (Eq, Ord, Show)
instance (Num a) => Num (ExprTree a) where
...
fromInteger i = Leaf (0%1) i -- <--error
instance Show (ExprTree a) where
show (Leaf l a) = show a -- <-- error
show (Node l f lb rb) = (show lb)++" "++(show l)
++(show f)++" "++(show rb)++"\n"
instance Eval (Val a) where
eval (Var v) n = n
eval a _ = a -- <-- error
I think this problems – are all of the same kind. And the NOT understanding the difference between class and type and so forth in a more than trivial setting – is a hole in the basis of my haskell programming; so i really want to understand this not to solve any homework.
Note: The label is a Rational – which makes inserting and searching much easier, than labelling with natural numbers or integers.
Thanks in advance!
The problem with your
fromIntegeris thatineeds to be converted to aVal a.The
Valwrapper makes it aVal; the innerfromIntegercreates ana, which is a caller-specified type, which we know can be created withfromIntegerbecause of theNum aconstraint) from theInteger. Pay close attention to that last: it’s the reason behind typeclasses. TheNum a =>constraint insures that, given ana, we know that we can use any of theNuminstance methods on it.The other problem is the same issue in reverse: you are calling
show, but you haven’t done anything to make sure thatshowmakes sense on ana.The problem with
Evalis slightly different:ajust appears without any source, so the compiler doesn’t know anything about it. In particular,eval a _ = arequires that anebe a valida— butais an unknown, so the compiler correctly says “what?”. For this one you need to think about what you’re really trying to do; the simplest solution is to drop theeand useaeverywhere, but is that really what you intended?