Haskell: Using the same operator on different types in a function -
i'm writing simple interpreter in haskell. have 3 possible variable types: bool, int , string. avoid repetition in evaluating comparisons, i've written function takes 2 expressions , operator:
data value = intval integer | stringval string | boolval bool | ... evalcomparison :: ord => exp -> (a -> -> bool) -> exp -> result value evalcomparison expr1 op expr2 = val1 <- evalexp expr1 val2 <- evalexp expr2 return $ boolval $ case (val1, val2) of (intval i1, intval i2) -> op i1 i2 (*) (stringval s1, stringval s2) -> op s1 s2 (**) (boolval b1, boolval b2) -> op b1 b2 (***) otherwise -> error "expected values of same type!" it's intended usage is, example:
evalexp :: exp -> result value ... evalexp (elessthen e1 e2) = evalcomparison e1 (<) e2 (and on other comparison operators).
the problem - doesn't work. ghc says couldn't match type integer [char] in line (**) , integer bool in line (***).
i think know problem lies: once a operator's type determined integer in line (*), cannot changed. question twofold:
why problem arise, provided result type (
bool) same regardless of operator's arguments' types?what can done make work?
the type signature a -> -> bool says there must exist type a op has type. want work more one type a. can't in haskell '98.
if turn on rank-2 types (or rank-n types), can do
evalcomparison :: exp -> (forall a. -> -> bool) -> exp -> result value this says whatever pass in op has work multiple types a. in fact, says op has work all possible types a. that's much. want closer to
evalcomparison :: exp -> (forall a. ord => -> -> bool) -> exp -> result value
this says op has work every possible a implements ord.
although frankly @ point, might call compare explicitly in case-expression. have evalcomparison return ordering, , apply ordering -> result value that. ordering 1 type, should make things simpler.
Comments
Post a Comment