Любители хаскелла, расскажите мне про них.
Например, я пишу компилятор для такого языка:
data Expr = S String
| I Int
| D Double
| Plus Expr Expr
| Minus Expr Expr
и типов у меня всего один (строки, даблс и интс это все один тип и их можно из друг друга вычитать и складывать).
Вот я пишу eval:
eval :: Expr -> Expr
eval (Plus e1 e2) = evalBinaryOp (+) e1 e2
eval (Minus e1 e2) = evalBinaryOp (-) e1 e2
eval e = e
где
evalBinaryOp :: Num a => (a -> a -> a) -> Expr -> Expr -> Expr
evalBinaryOp op expr1 expr2 = case (eval expr1, eval expr2) of
(D d1, e2) -> let d2 = toDouble e2
in D (op d1 d2)
(e1, D d2) -> let d1 = toDouble e1
in D (op d1 d2)
(I i1, e2) -> let i2 = toInt e2
in I (op i1 i2)
(e1, I i2) -> let i1 = toInt e1
in I (op i1 i2)
_ -> I 0
toDouble :: Expr -> Double
toInt :: Expr -> Int
В этом коде проблема: фунция op не полиморфна. Как мне изменить тип evalBinaryOp чтобы она стала полиморфной как (+)? Я плохо понимаю forall, расскажите кто разобрался.