switch (collection.getFirst()) { case Integer i -> LogUtils.notice(i.toString()); case String s -> LogUtils.notice(s); case Empty em -> LogUtils.warn("Received an empty element"); default -> LogUtils.error("unexpected type"); }
classVisitorimplementsIVisitor{ @Override public Integer visitLiteral(IExpr.Literal e){ return e.value; } @Override public Integer visitAdd(IExpr.Add e){ return e.left.accept(this) + e.right.accept(this); } @Override public Integer visitSub(IExpr.Sub e){ return e.left.accept(this) - e.right.accept(this); } }
publicstaticvoidmain(String[] args){ var expr = new IExpr.Add(new IExpr.Literal(10),new IExpr.Sub(new IExpr.Literal(7), new IExpr.Literal(3))); System.out.println(expr.eval()); } }
classPair[A, B](val fst: A, val snd: B) enum IExpr[A] { caseNum(val value: Int) extendsIExpr[Int] caseBool(val value: Boolean) extendsIExpr[Boolean] caseAdd(val left: IExpr[Int], val right: IExpr[Int]) extendsIExpr[Int] caseSub(val left: IExpr[Int], val right: IExpr[Int]) extendsIExpr[Int] caseAnd(val left: IExpr[Boolean], val right: IExpr[Boolean]) extendsIExpr[Boolean] caseOr(val left: IExpr[Boolean], val right: IExpr[Boolean]) extendsIExpr[Boolean] // case Eq(val left: IExpr[A], val right: IExpr[A]) extends IExpr[A] // case Ne(val left: IExpr[A], val right: IExpr[A]) extends IExpr[A] caseNot(val value: IExpr[Boolean]) extendsIExpr[Boolean] }
defeval[A](expr: IExpr[A]): A = expr match { caseIExpr.Num(v) => v caseIExpr.Bool(v) => v caseIExpr.Add(a, b) => eval(a) + eval(b) caseIExpr.Sub(a, b) => eval(a) - eval(b) caseIExpr.And(a, b) => eval(a) && eval(b) caseIExpr.Or(a, b) => eval(a) || eval(b) // case IExpr.Eq(a, b) => eval(a).equals(eval(b)) // case IExpr.Ne(a, b) => ! eval(a).equals(eval(b)) caseIExpr.Not(v) => !(eval(v)) case _ => throwIllegalStateException("Unknown type") }
val exp1 = IExpr.Not((IExpr.And(IExpr.Bool(false), IExpr.Bool(true)))) val exp2 = IExpr.Add(IExpr.Num(3), IExpr.Num(5))
dataExpr a where IntLit :: Int -> ExprInt BoolLit :: Bool -> ExprBool Add :: ExprInt -> ExprInt -> ExprInt Sub :: ExprInt -> ExprInt -> ExprInt And :: ExprBool -> ExprBool -> ExprBool Or :: ExprBool -> ExprBool -> ExprBool Eq :: Eq a => Expr a -> Expr a -> ExprBool Ne :: Eq a => Expr a -> Expr a -> ExprBool Not :: ExprBool -> ExprBool
eval :: Expr a -> a eval (IntLit n) = n eval (BoolLit b) = b eval (Add a b) = eval a + eval b eval (Sub a b) = eval a - eval b eval (And a b) = eval a && eval b eval (Or a b) = eval a || eval b eval (Eq a b) = eval a == eval b eval (Ne a b) = eval a /= eval b eval (Not v) = not $ eval v
main = do let exp = Not (Ne (BoolLitFalse) (Eq (Add (IntLit3) (IntLit5)) (Sub (IntLit10) (IntLit2)))) in print . eval $ exp