I want to write down math expressions using Haskell. For example:
foo = (3 * 'x' + 2 * 'y' -- => 3x+2y
Is there a way to rewrite the implementation from below in such way that Add
and Mul
could be replaced by operators +
and *
respectively?
data Expr = Const Integer
| Var Char
| Add Expr Expr
| Mul Expr Expr
deriving (Show)
...
foo = Add (Mul (Const 3) (Var 'x')) (Mul (Const 3) (Var 'y'))
Ugly as hell.
Using TypeOperators won't work too, it requires operators to be preceded by :
.
infixl 4 :+:
infixl 5 :*:, :/:
infixr 6 :^:
data Expr = Const Integer
| Var Char
| Expr :+: Expr
| Expr :*: Expr
| Expr :^: Expr
| Expr :/: Expr
deriving (Eq, Show)
The declaration of expression would become:
foo = (Const 3 :*: Var 'x') :+: (Const 2 :*: Var 'y')
Less ugly, but still bad. Any ideas?
{-# LANGUAGE OverloadedStrings #-}
import Data.String
data Expr = Const Integer
| Var Char
| Add Expr Expr
| Mul Expr Expr
deriving (Show)
instance Num Expr where
(+) = Add
(*) = Mul
fromInteger = Const
abs = undefined
signum = undefined
negate = undefined
instance IsString Expr where
fromString s = Var (head s)
main = do
let expr = 3 * "x" + 2 * "y" :: Expr
print expr