/// 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 ++ “!”
Quick Answer Instagram does not keep a history of the Reels you watch. The app…
What works well for one team becomes chaos when scaled to a department or company…
Inspired by the super-popular anime and manga series Bleach, Type Soul is a Roblox game…
The hospitality sector is embracing a tech revolution with the introduction of the Zerith H1…
The Vivobook S14 OLED delivers impressive value by combining a sleek, lightweight design with the…
Infinite Craft is a fun sandbox game that challenges players to create new items by combining…