Skip to content

Instantly share code, notes, and snippets.

@mkakh
Last active September 8, 2019 11:29
Show Gist options
  • Save mkakh/30c0c3170d03045f84d591bd081910e8 to your computer and use it in GitHub Desktop.
Save mkakh/30c0c3170d03045f84d591bd081910e8 to your computer and use it in GitHub Desktop.
練習用の駄作
use std::convert::From;
use std::cmp::Ordering;
use std::fmt;
use std::rc::Rc;
use Nat::*;
#[derive(Clone, PartialEq)]
enum Nat {
Succ(Rc<Nat>),
Zero,
}
impl Nat {
fn init() -> Self {
Zero
}
fn succ(&self) -> Self {
Succ(Rc::new(self.clone()))
}
fn add(&self, n: &Nat) -> Self {
match n {
Succ(k) => { self.succ().add(k) }
Zero => { self.clone() }
}
}
fn mul(&self, n: &Nat) -> Self {
fn _mul(n: &Nat, ct: &Nat, ret: Nat) -> Nat {
match ct {
Succ(k) => { _mul(n, k, ret.add(n)) }
Zero => { ret }
}
}
_mul(self, n, Zero)
}
fn pow(&self, n: &Nat) -> Self {
fn _pow(n: &Nat, ct: &Nat, ret: Nat) -> Nat {
match ct {
Succ(k) => { _pow(n, k, ret.mul(n)) }
Zero => { ret }
}
}
_pow(self, n, Zero.succ())
}
}
impl PartialOrd for Nat {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (self, other) {
(Zero, Zero) => Some(Ordering::Equal),
(Succ(ref a), Succ(ref b)) => (PartialOrd::partial_cmp(a, b)),
(Zero, Succ(_)) => Some(Ordering::Less),
(Succ(_), Zero) => Some(Ordering::Greater),
}
}
}
impl From<u32> for Nat {
fn from(n: u32) -> Self {
if n <= 0 { Zero }
else { Succ(Rc::new(Self::from(n-1))) }
}
}
impl From<&Nat> for u32 {
fn from(n: &Nat) -> Self {
match n {
Succ(k) => { 1 + Self::from(k.as_ref()) }
Zero => { 0 }
}
}
}
impl fmt::Display for Nat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Succ(k) => { write!(f, "S({})", k.to_string()) }
Zero => { write!(f, "Z") }
}
}
}
fn main() {
let zero: Nat = Nat::init();
println!("zero: {}", zero);
println!("zero-succ-succ: {}\n", zero.succ().succ());
let two: Nat = 2.into();
println!("2: {}", two);
let three: Nat = 3.into();
println!("3: {}\n", three);
println!("(+) 2 3: {}", Nat::add(&two, &three));
println!("2+3: {}", two.add(&three));
println!("(2+3)_u32: {}\n", u32::from(&two.add(&three)));
println!("(*) 2 3: {}", Nat::mul(&two, &three));
println!("2*3: {}", two.mul(&three));
println!("(2*3)_u32: {}\n", u32::from(&two.mul(&three)));
println!("(^) 2 3: {}", Nat::pow(&two, &three));
println!("2^3: {}", two.pow(&three));
println!("(2^3)_u32: {}\n", u32::from(&two.pow(&three)));
println!("2 == 3?: {}", two == three);
println!("2 == 2?: {}", two == two);
println!("2 != 2?: {}", two != two);
println!("2 == Zero-succ-succ?: {}", two == Zero.succ().succ());
println!("2 < 3?: {}", two < three);
println!("2 <= 3?: {}", two <= three);
println!("2 > 3?: {}", two > three);
println!("2 >= 3?: {}", two >= three);
println!("2 < Zero-succ-succ?: {}", two < Zero.succ().succ());
println!("2 <= Zero-succ-succ?: {}", two <= Zero.succ().succ());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment