[英]Haskell - Calculate string “let X = 3 in + X X”
嗨,我需要帮助来计算类型。 假设整个程序采用一个字符串,将其解析,最后计算一个值。 我开始的字符串可能是这样的:“ let X = + 1 2 in * X 2 - X
”。 当我解析它时,我会得到:“ Let (Vari X) (Sum (Lit 1) (Lit 2)) (Mul (Vari X) (Lit 2)))
”。 目前,我可以解析“ * + 2 3 * 2 + 6-2”和之前的表达式。 但是我无法计算前面的表达式“ let X = + 1 2 in * X 2 - X
”。 如果有人能指出正确的方向,我会很高兴,因为现在,我真的不知道如何进行这项工作。 谢谢
码:
data Chara = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z deriving (Eq, Show)
data Number = Single Int | Many Int Number deriving (Eq, Show)
data Expr = Lit Int | Sub Expr | Sum Expr Expr | Mul Expr Expr | Vari Chara | Let Expr Expr Expr
deriving Show
--Want to calculate this
--Let (Vari X) (Sum (Lit 1) (Lit 2)) (Mul (Vari X) (Lit 2)))
calculate :: Expr -> Int
calculate (Sub a) = let e = calculate a in (-e)
calculate (Sum a b) = let e = calculate a
r = calculate b
in (e+r)
calculate (Mul a b) = let e = calculate a
r = calculate b
in (e*r)
calculate (Lit a) = a
您需要在AST中执行变量替换 。 即你需要一个功能
substitute :: (Chara, Expr) -> Expr -> Expr
给定一对要替换的变量和用其 替换的 表达式,它们将遍历树并执行该替换。 这基本上意味着:如果找到Vari
,只需将其替换为替换项即可。 如果找到带有子表达式之类的东西,例如Sum ab
,则递归到这些子表达式中,然后用结果重建运算符,即
Sum (substitute s a) (substitute s b)
然后, calculate (Let var subst expr) = ...
是对substitute
函数的直接调用。
奇迹般有效
calculate :: Expr -> Int
calculate (Sub a) = let e = calculate a in (-e)
calculate (Sum a b) = let e = calculate a
r = calculate b
in (e+r)
calculate (Mul a b) = let e = calculate a
r = calculate b
in (e*r)
calculate (Let a b c) = calculate (substitute (getCharaFromExpr a) b c)
calculate (Lit a) = a
substitute :: Chara -> Expr -> Expr -> Expr
substitute x y (Lit a) = Lit a
substitute x y (Vari a) | x == a = y
| otherwise = Vari a
substitute x y (Sum a b) = Sum (substitute x y a) (substitute x y b)
substitute x y (Mul a b) = Mul (substitute x y a) (substitute x y b)
substitute x y (Sub a) = Sub (substitute x y a)
substitute x y (Let a b c) = Let (substitute x y a) (substitute x y b) (substitute x y c)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.