/// A sum type for the expression.
/// An expression is either a var (which is a string), a constant
/// (which is an integer), an addition (made of two expressions)
/// or a multiplication (also made of two expressions).
type Expr =
| Var of string
| Const of int
| Add of Expr * Expr
| Mul of Expr * Expr
/// Simplify a single component of the expression. This function
/// takes an expression and use pattern matching to select the
/// right approach based on type and value. For example, if we
/// add a constant 0 to some x (which can be expression), then
/// we return x.
let simplify1 e =
match e with
| Add (Const 0, x)
| Add (x, Const 0)
| Mul (x, Const 1)
| Mul (Const 1, x) -> x
| Mul (x, Const 0)
| Mul (Const 0, x) -> Const 0
| Add (Const a, Const b) -> Const (a + b)
| Mul (Const a, Const b) -> Const (a * b)
/// Recursive function to simplify an entire expression.
| _ -> e
let rec simplify e =
match e with
| Add (x, y) -> Add (simplify x, simplify y)
| Mul (x, y) -> Mul (simplify x, simplify y)
/// Return the value string if the expression can be reduced to a constant.
| _ -> e
|> simplify1
let exprStr e =
match e with
| Const x -> string x
| _ -> "The expression could not be simplified to a constant."
/// The |> operator sends the result on its left to its right, for example
/// "5.0 |> log |> sqrt" computes log(5.0) and then the square root of the
/// result. This is nice because it allows a more natural left-to-right
/// flow for functional programming.
[<EntryPoint>]
let main argv =
Add (Mul (Add (Const 1, Mul (Const 0, Var "x")), Const 3), Const 12)
|> simplify
|> exprStr
|> printf "%s"
0 /// F#'s main returns 0 for success à la C
import Data.Map (Map)
import qualified Data.Map as Map
capitals = Map.fromList [("Finland", "Helsinki"), ("France", "Paris"),
("Japan", "Tokyo"), ("South Korea", "Seoul"), ("Arrakis", "Arrakeen")]
lookupCapitals country = case Map.lookup country capitals of
Just capital -> "The capital of " ++ country ++ " is " ++ capital ++ "."
Nothing -> "Is " ++ country ++ " even a country?"
ghci> lookupCapitals "Arrakis"
"The capital of Arrakis is Arrakeen."
ghci> lookupCapitals "Canada"
"Is Canada even a country?"
data Expr =
Var String
| Const Int
| Add Expr Expr
| Mult Expr Expr
simplify1 :: Expr -> Expr
simplify1 e = case e of
Add (Const 0) x -> x
Add x (Const 0) -> x
Add (Const a) (Const b) -> Const $ a + b
Mult x (Const 0) -> Const 0
Mult (Const 0) x -> Const 0
Mult x (Const 1) -> x
Mult (Const 1) x -> x
Mult (Const a) (Const b) -> Const $ a * b
_ -> e
simplify :: Expr -> Expr
simplify e = case e of
Add x y -> simplify1 $ Add (simplify x) (simplify y)
Mult x y -> simplify1 $ Mult (simplify x) (simplify y)
_ -> simplify1 e
e = Add (Mult (Add (Const 1) (Mult (Const 0) (Var "x"))) (Const 3)) (Const 12)
s = simplify e
main = putStrLn $ case s of
Const x -> show x
_ -> "Could not simplify the expression to a constant."
x = log (sqrt (exp 5.0))
y = log $ sqrt $ exp 5.0
let z = exp 5.0 |> sqrt |> log
(|>) :: t0 -> (t0 -> t1) -> t1
(|>) x f = f x
-- Now valid Haskell:
z = exp 5.0 |> sqrt |> log
object Simplify {
sealed abstract class Expr { override def toString = show(this) }
case class Variable(name: String) extends Expr
case class Const(value: Int) extends Expr
case class Add(left: Expr, right: Expr) extends Expr
case class Mult(left: Expr, right: Expr) extends Expr
def evalOne(e: Expr): Expr = e match {
case Add(Const(0), r) => r
case Add(l, Const(0)) => l
case Add(Const(a), Const(b)) => Const(a + b)
case Mult(Const(0), r) => Const(0)
case Mult(l, Const(0)) => Const(0)
case Mult(Const(1), r) => r
case Mult(l, Const(1)) => l
case Mult(Const(a), Const(b)) => Const(a * b)
case _ => e
}
def eval(e: Expr): Expr = e match {
case Add(l, r) => evalOne(Add(eval(l), eval(r)))
case Mult(l, r) => evalOne(Mult(eval(l), eval(r)))
case _ => e
}
def show(e: Expr) = e match {
case Const(x) => print(x)
case _ =>
print("The expression could not be simplified to a constant.")
}
def main(args: Array[String]) {
var e = Add(Mult(Add(Const(1), Mult(Const(0), Variable("x"))),
Const(3)), Const(12))
var s = eval(e)
print(s)
}
}
#include <iostream>
#include <string>
#include <boost/variant>
struct Add;
struct Mult;
using Expr = boost::variant<
int,
std::string,
boost::recursive_wrapper<Add>,
boost::recursive_wrapper<Mult>>;
struct Add {
Expr left, right;
Add(const Expr &left_, const Expr &right_) : left(left_), right(right_) {
}
};
struct Mult {
Expr left, right;
Mult(const Expr &left_, const Expr &right_) : left(left_), right(right_) {
}
};
struct add_visit : public boost::static_visitor<Expr> {
Expr operator()(int l, int r) const {
return Expr(l + r);
}
template<class X> Expr operator()(int l, const X &x) const {
return l == 0? Expr(x) : Add(Expr(l), Expr(x));
}
template<class X> Expr operator()(const X &x, int r) const {
return r == 0? Expr(x) : Add(Expr(r), Expr(x));
}
template<class X, class Y>
Expr operator()(const X &x, const Y &y) const {
return Add(Expr(x), Expr(y));
}
};
struct mul_visit : public boost::static_visitor<Expr> {
Expr operator()(int l, int r) const {
return Expr(l * r);
}
template<class X> Expr operator()(int l, const X &x) const {
return l == 0? Expr(0) : (l == 1? Expr(x) : Mult(Expr(l), Expr(x)));
}
template<class X> Expr operator()(const X &x, int r) const {
return r == 0? Expr(0) : (r == 1? Expr(x) : Mult(Expr(r), Expr(x)));
}
template<class X, class Y>
Expr operator()(const X &x, const Y &y) const {
return Mult(Expr(x), Expr(y));
}
};
struct simplify1 : public boost::static_visitor<Expr> {
Expr operator()(const Add &a) const {
return boost::apply_visitor(add_visit(), a.left, a.right);
}
Expr operator()(const Mult &m) const {
return boost::apply_visitor(mul_visit(), m.left, m.right);
}
template<class X> Expr operator()(const X &x) const {
return Expr(x);
}
};
struct simplify : public boost::static_visitor<Expr> {
Expr operator()(const Add &a) const {
auto left = boost::apply_visitor(simplify(), a.left);
auto right = boost::apply_visitor(simplify(), a.right);
auto add_lr = boost::apply_visitor(add_visit(), left, right);
return boost::apply_visitor(simplify1(), add_lr);
}
Expr operator()(const Mult &m) const {
auto left = boost::apply_visitor(simplify(), m.left);
auto right = boost::apply_visitor(simplify(), m.right);
auto mul_lr = boost::apply_visitor(mul_visit(), left, right);
return boost::apply_visitor(simplify1(), mul_lr);
}
template<class X> Expr operator()(const X &x) const {
return x;
}
struct print_expr : public boost::static_visitor<std::string> {
};
std::string operator()(int x) const { return std::to_string(x); };
std::string operator()(const Expr &e) const {
return "The expression could not be simplified to a constant.";
};
};
int main() {
auto e = Expr(Add(
Expr(Mult(Expr(Add(Expr(1), Expr(Mult(Expr(0), Expr("x"))))),
Expr(3))), Expr(12)));
auto s = boost::apply_visitor(simplify(), e);
std::cout << boost::apply_visitor(print_expr(), s) << std::endl;
return 0;
}
abstract Expr
type Const <: Expr; val::Int end
type Var <: Expr; name::String end
type Add <: Expr; left::Expr; right::Expr end
type Mult <: Expr; left::Expr; right::Expr end
add(x::Const, y::Const) = Const(x.val + y.val)
add(x::Const, y::Expr) = x.val == 0? y : Add(x, y)
add(x::Expr, y::Const) = add(y, x)
add(x::Expr, y::Expr) = Add(x, y)
mult(x::Const, y::Const) = Const(x.val * y.val)
mult(x::Const, y::Expr) = x.val == 1? y : (x.val == 0? Const(0) : Mult(x, y))
mult(x::Expr, y::Const) = mult(y, x)
mult(x::Expr, y::Expr) = Mult(x, y)
simplify1(a::Add) = add(a.left, a.right)
simplify1(m::Mult) = mult(m.left, m.right)
simplify1(e::Expr) = e
simplify(a::Add) = simplify1(Add(simplify(a.left), simplify(a.right)))
simplify(m::Mult) = simplify1(Mult(simplify(m.left), simplify(m.right)))
simplify(e::Expr) = e
printExpr(c::Const) = print(c.val)
printExpr(e::Expr) =
print("The expression could not be simplified to a constant.")
e = Add(Mult(Add(Const(1), Mult(Const(0), Var("x"))), Const(3)), Const(12))
s = simplify(e)
printExpr(s)
solve(pre::(Object -> Bool), ...)
solve(fun::(Object -> Object), ...)
let world = “世界” in print $ “Hello ” ++ world ++ “!”
If Tesla shares were a road trip, 2025 has been like experiencing a bumpy ride…
Ever get the urge to learn something new? Well you aren’t going to become a…
Prepare yourselves to feel what Christmas in July means, folks! Nintendo has announced to drop…
Nvidia’s stock, already enjoying elite status, appears to have received a boost of adrenaline after…
I see a lot of recommendations online and it’s already obvious there are bad eggs…
Nintendo and The Pokemon company have recently scored a patent and could send shockwaves in…