我想用Haskell写下数学表达式。 例如:
foo = (3 * 'x' + 2 * 'y' -- => 3x+2y
有没有办法从下面重写实现,Add
和Mul
可以分别由运算符+
和*
替换?
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'))
丑陋地狱。
使用TypeOperators也不会起作用,它要求运算符前面加:
。
infixl 4 :+:
infixl 5 :*:, :/:
infixr 6 :^:
data Expr = Const Integer
| Var Char
| Expr :+: Expr
| Expr :*: Expr
| Expr :^: Expr
| Expr :/: Expr
deriving (Eq, Show)
表达声明将成为:
foo = (Const 3 :*: Var 'x') :+: (Const 2 :*: Var 'y')
不那么难看,但仍然很糟糕。有什么想法吗?
答案 0 :(得分:7)
{-# 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
答案 1 :(得分:4)
您可以为表达式数据类型创建Num / Real实例。
instance Num Expr where
a + b = Add a b
a * b = Mul a b
fromIntegral a = Const a
x = Var 'x'
y = Var 'y'
result = 2 * x + 3 * y