From 38df5357c100eefd50a1114411b4af42c56e70b8 Mon Sep 17 00:00:00 2001 From: Grant Wuerker Date: Thu, 13 Jun 2024 19:50:03 -0600 Subject: [PATCH] monad --- library/core/src/monad copy.fe | 173 ++++++++++++++++++++++++++++++ library/core/src/monad.fe | 174 +++++++++++++++++++++++++++++++ library/core/src/monad/map.fe | 0 library/core/src/monad/option.fe | 2 +- library/core/src/num.fe | 28 ++--- library/core/src/num/arith.fe | 153 ++++++++++++++------------- 6 files changed, 439 insertions(+), 91 deletions(-) create mode 100644 library/core/src/monad copy.fe create mode 100644 library/core/src/monad/map.fe diff --git a/library/core/src/monad copy.fe b/library/core/src/monad copy.fe new file mode 100644 index 0000000000..4f5e1e8e47 --- /dev/null +++ b/library/core/src/monad copy.fe @@ -0,0 +1,173 @@ +// use self::option::Option + +// trait Applicative +// where Self: * -> * +// { +// fn pure(t: T) -> Self +// } + +// impl Applicative for Option { +// fn pure(t: T) -> Self { +// Option::Some(t) +// } +// } + +// trait Monad: Applicative +// where Self: * -> * +// { +// fn bind(self: Self) -> Self where F: Fn> +// } + +// impl Monad for Option { +// fn bind(self: Self) -> Self where F: Fn> { +// match self { +// Self::Some(self) => F::exec(t: self) +// Self::None => Self::None +// } +// } +// } + +// fn foo(f: F) +// where F: Fn(u8, u8, u8) -> u8 { +// where F: Fn<{u8, u8, u8}, u8> + +// } + +// fn f(u8, u8, u8) -> u8 {} // (u8, u8, u8) -> u8 +// fn g((u8, u8, u8)) -> u8 {} //((u8,u8,u8)) -> u8 + +// fn main() { +// f(1, 2, 3) // f.exec((1, 2, 3)) + +// let x = (1, 2, 3) +// f(x) +// g(x) + +// let args = {1, 2, 3} +// args.push(1) + +// let args = (1, 2, 3) +// f (1, 2, 3) +// f args + +// let x = ((u8, u8, u8)) +// let x = ((u8, u8, u8),) + +// f(args..) // f(x, y) f ( +// } +// (u8, u8, u8) -> u8 +// u8 -> u8 -> u8 -> u8 + + + +// impl Fn<((u8, u8, u8)), u8> for G + +// impl Fn<(u8, u8, u8), u8> for Foo { + +// } + +// trait Fn where T: FnArgs { +// fn exect(&self, t: T) -> U +// } + +// trait Fn +// where Arg: Tuple +// { +// fn call(self, arg : Arg) -> Ret +// } + +// trait FnMut where T: FnArgs { +// fn exect(&mut self, t: T) -> U +// } + +// trait Tuple; + +// fn map(t: T, f: F) -> U +// where F: Fn(T) -> U {...} + +// type MyFn = () + +// impl Fn for Foo { +// fn exec(&self, t: T) -> U { +// t.element(0) +// t.len() +// } +// } + +// impl Fn<(u8, u8>, Option> for MyFn { +// fn exec(t: (bool, bool)) -> Option { +// let (a, b) = t +// f(a, b) +// } +// } + +// #test +// fn my_test() { +// let f: MyFn = () +// let a = Option::Some(true).bind<_, _, _>(f) +// let a: Option = Option::Some(true).bind(f) +// } + + +// sub x y = x - y +// f = sub 1 // f 2 == 1 - 2 +// g = `sub` 1 // g 2 == 2 - 1 + + +// enum Result { +// Ok(T) +// Err(E) +// } +// impl Functor for Result<*, E> { // or Result<_, E> maybe? +// fn map>(self: Self, _ f: F) -> Self { +// match self { +// Result::Ok(a) => { +// return Result::Ok(f(a)) +// } +// Result::Err(e) => { +// return Result::Err(e) +// } +// } +// } +// } + + +// enum Res { // Result +// Err(E) +// Ok(T) +// } +// impl Functor for Res { +// fn map>(self: Self, _ f: F) -> Self { +// match self { +// Result::Ok(a) => { +// return Result::Ok(f(a)) +// } +// Result::Err(e) => { +// return Result::Err(e) +// } +// } +// } +// } + + + +// fn main() { +// let r = foo() +// r.map(|t| ...) +// } + + +// enum Result1 + +// Result<_, E> + +// Flip (Result) + + + +// ((+) `foldl` 0) [1..5] +// ((`foldl` 0) [1..5]) (+) + +// flip :: (a -> b -> c) -> b -> a -> c +// f :: a -> b -> c -> d -> e +// flip f :: b -> a -> c -> d -> e diff --git a/library/core/src/monad.fe b/library/core/src/monad.fe index e69de29bb2..38a8d42e1c 100644 --- a/library/core/src/monad.fe +++ b/library/core/src/monad.fe @@ -0,0 +1,174 @@ +use self::option::Option +use super::num::Num +use super::num::arith::HAdd + +trait Tuple { } + +trait Fn where Args: Tuple { + fn exec(self, args: Args) -> Ret +} + +pub enum Option { + Some(T), + None +} + +trait Applicative +where Self: * -> * +{ + fn pure(t: T) -> Self +} + +impl Applicative for Option { + fn pure(t: T) -> Self { + Option::Some(t) + } +} + +trait Monad: Applicative +where Self: * -> * +{ + fn bind(self: Self, morph: Morph) -> Self + where Morph: Fn<1, (Source), Self>, (Source): Tuple<1> +} + +impl Monad for Option { + fn bind(self: Self, morph: Morph) -> Self + where Morph: Fn<1, (Source), Self>, (Source): Tuple<1> + { + match self { + Self::Some(self) => morph.exec(args: (self, )) + Self::None => Self::None + } + } +} + +struct BindAdd { n: N } + +impl *, N> Fn<1, (N), M> for BindAdd +where M: Monad, N: HAdd, (N): Tuple<1> +{ + fn exec(self, args: (N)) -> M { + M::pure(t: args.0.add(rhs: self.n)) + } +} + +impl *, N> HAdd> for M +where M: Monad, N: HAdd, (N): Tuple<1> +{ + fn add(self, rhs: N) -> M { + self.bind>(morph: BindAdd { n: rhs }) + } +} + +// impl HAdd> for Option { +// fn add(self, rhs: u8) -> Option { +// self.bind>(morph: BindAdd { n: rhs }) +// } +// } + +impl Tuple<1> for (u8) { } + +fn test_monadd() { + let a: Option = Option::Some(42) + let b: u8 = 26 + let c: Option = a.add(rhs: b) +} + +// type MyFn = () + +// impl Fn<1, (bool), Option> for MyFn { +// fn exec(self, args: (bool)) -> Option { +// Option::Some(0) +// } +// } + +// impl Tuple<1> for (bool) { } + +// #test +// fn my_test() { +// let f: MyFn = () +// let a = Option::Some(true).bind(f) +// } + +// fn map(t: T, f: F) -> U +// where F: Fn(T) -> U {...} + +// type MyFn = () + +// impl Fn for Foo { +// fn exec(&self, t: T) -> U { +// t.element(0) +// t.len() +// } +// } + +// impl Fn<(u8, u8>, Option> for MyFn { +// fn exec(t: (bool, bool)) -> Option { +// let (a, b) = t +// f(a, b) +// } +// } + +// sub x y = x - y +// f = sub 1 // f 2 == 1 - 2 +// g = `sub` 1 // g 2 == 2 - 1 + + +// enum Result { +// Ok(T) +// Err(E) +// } +// impl Functor for Result<*, E> { // or Result<_, E> maybe? +// fn map>(self: Self, _ f: F) -> Self { +// match self { +// Result::Ok(a) => { +// return Result::Ok(f(a)) +// } +// Result::Err(e) => { +// return Result::Err(e) +// } +// } +// } +// } + + +// enum Res { // Result +// Err(E) +// Ok(T) +// } +// impl Functor for Res { +// fn map>(self: Self, _ f: F) -> Self { +// match self { +// Result::Ok(a) => { +// return Result::Ok(f(a)) +// } +// Result::Err(e) => { +// return Result::Err(e) +// } +// } +// } +// } + + + +// fn main() { +// let r = foo() +// r.map(|t| ...) +// } + + +// enum Result1 + +// Result<_, E> + +// Flip (Result) + + + +// ((+) `foldl` 0) [1..5] +// ((`foldl` 0) [1..5]) (+) + +// flip :: (a -> b -> c) -> b -> a -> c +// f :: a -> b -> c -> d -> e +// flip f :: b -> a -> c -> d -> e diff --git a/library/core/src/monad/map.fe b/library/core/src/monad/map.fe new file mode 100644 index 0000000000..e69de29bb2 diff --git a/library/core/src/monad/option.fe b/library/core/src/monad/option.fe index 418b6de817..6e8bfa4798 100644 --- a/library/core/src/monad/option.fe +++ b/library/core/src/monad/option.fe @@ -1,4 +1,4 @@ -enum Option { +pub enum Option { Some(Inner), None } \ No newline at end of file diff --git a/library/core/src/num.fe b/library/core/src/num.fe index 715e250beb..63ffeb9792 100644 --- a/library/core/src/num.fe +++ b/library/core/src/num.fe @@ -1,19 +1,21 @@ -// use ingot::num::arith::{Add, Sub, Mul, Div, Neg, Mod, Exp} +use ingot::num::arith::{Add, Sub, Mul, Div, Neg, Mod, Pow} -// pub trait Num: Add + Sub + Mul + Div + Exp { } +pub trait Num: Add + Sub + Mul + Div + Pow { } -// pub trait Complex: Num + Neg { -// fn re() -> N -// fn im() -> N -// } +pub trait Complex: Num + Neg { + fn re() -> N + fn im() -> N +} -// pub trait Real: Num + Neg { } +pub trait Real: Num + Neg { } -// pub trait Frac: Num + Neg { -// fn nu() -> N -// fn de() -> N -// } +pub trait Frac: Num + Neg { + fn nu() -> N + fn de() -> N +} -// pub trait Int: Num + Mod + Neg { } +pub trait Int: Num + Mod + Neg { } -// pub trait Nat: Num + Mod { } \ No newline at end of file +pub trait Nat: Num + Mod { } + +impl Num for u8 { } \ No newline at end of file diff --git a/library/core/src/num/arith.fe b/library/core/src/num/arith.fe index 4940e47c5c..e360953493 100644 --- a/library/core/src/num/arith.fe +++ b/library/core/src/num/arith.fe @@ -1,77 +1,76 @@ -// /// Addition (e.g. `x + y`) -// pub trait HAdd { -// fn add(self, rhs: Rhs) -> Out -// } - -// /// Subtraction (e.g. `x - y`) -// pub trait HSub { -// fn sub(self, rhs: Rhs) -> Out -// } - -// /// Multiplication (e.g. `x * y`) -// pub trait HMul { -// fn mul(self, rhs: Rhs) -> Out -// } - -// /// Division (e.g. `x / y`) -// pub trait HDiv { -// fn div(self, rhs: Rhs) -> Out -// } - -// /// Modulo (e.g. `x % y`) -// pub trait HMod { -// fn modulo(self, rhs: Rhs) -> Out -// } - -// /// Power (e.g. `x ** y`) -// pub trait HPow { -// fn pow(self, rhs: Rhs) -> Out -// } - -// /// Neg (e.g. `-x`) -// pub trait HNeg { -// fn neg(self) -> Out -// } - -// pub trait HMod { -// fn modulo(self, rhs: Rhs) -> Out -// } - -// pub trait Add: HAdd { } - -// pub trait Sub: HSub { } - -// pub trait Mul: HMul { } - -// pub trait Div: HDiv { } - -// pub trait Pow: HPow { } - -// pub trait Mod: HMod { } - -// pub trait Neg: HNeg { } - - -// impl HAdd for i8 { fn add(self, rhs: Self) -> Self { self + rhs } } -// impl HSub for i8 { fn sub(self, rhs: Self) -> Self { self - rhs } } -// impl HMul for i8 { fn mul(self, rhs: Self) -> Self { self * rhs } } -// impl HDiv for i8 { fn div(self, rhs: Self) -> Self { self / rhs } } -// impl HNeg for i8 { fn neg(self) -> Self { -self } } - -// impl Add for i8 { } -// impl Sub for i8 { } -// impl Mul for i8 { } -// impl Div for i8 { } -// impl Neg for i8 { } - -// impl HAdd for u8 { fn add(self, rhs: Self) -> Self { self + rhs } } -// impl HSub for u8 { fn sub(self, rhs: Self) -> Self { self - rhs } } -// impl HMul for u8 { fn mul(self, rhs: Self) -> Self { self * rhs } } -// impl HDiv for u8 { fn div(self, rhs: Self) -> Self { self / rhs } } -// impl HNeg for u8 { fn neg(self) -> Self { -self } } - -// impl Add for u8 { } -// impl Sub for u8 { } -// impl Mul for u8 { } -// impl Div for u8 { } -// impl Neg for u8 { } +/// Addition (e.g. `x + y`) +pub trait HAdd { + fn add(self, rhs: Rhs) -> Out +} + +/// Subtraction (e.g. `x - y`) +pub trait HSub { + fn sub(self, rhs: Rhs) -> Out +} + +/// Multiplication (e.g. `x * y`) +pub trait HMul { + fn mul(self, rhs: Rhs) -> Out +} + +/// Division (e.g. `x / y`) +pub trait HDiv { + fn div(self, rhs: Rhs) -> Out +} + +/// Modulo (e.g. `x % y`) +pub trait HMod { + fn modulo(self, rhs: Rhs) -> Out +} + +/// Power (e.g. `x ** y`) +pub trait HPow { + fn pow(self, rhs: Rhs) -> Out +} + +/// Neg (e.g. `-x`) +pub trait HNeg { + fn neg(self) -> Out +} + +pub trait Add: HAdd { } + +pub trait Sub: HSub { } + +pub trait Mul: HMul { } + +pub trait Div: HDiv { } + +pub trait Pow: HPow { } + +pub trait Mod: HMod { } + +pub trait Neg: HNeg { } + +impl HAdd for i8 { fn add(self, rhs: Self) -> Self { self + rhs } } +impl HSub for i8 { fn sub(self, rhs: Self) -> Self { self - rhs } } +impl HMul for i8 { fn mul(self, rhs: Self) -> Self { self * rhs } } +impl HDiv for i8 { fn div(self, rhs: Self) -> Self { self / rhs } } +impl HPow for i8 { fn pow(self, rhs: Self) -> Self { self ** rhs } } +impl HNeg for i8 { fn neg(self) -> Self { -self } } + +impl Add for i8 { } +impl Sub for i8 { } +impl Mul for i8 { } +impl Div for i8 { } +impl Pow for i8 { } +impl Neg for i8 { } + +impl HAdd for u8 { fn add(self, rhs: Self) -> Self { self + rhs } } +impl HSub for u8 { fn sub(self, rhs: Self) -> Self { self - rhs } } +impl HMul for u8 { fn mul(self, rhs: Self) -> Self { self * rhs } } +impl HDiv for u8 { fn div(self, rhs: Self) -> Self { self / rhs } } +impl HPow for u8 { fn pow(self, rhs: Self) -> Self { self ** rhs } } +impl HNeg for u8 { fn neg(self) -> Self { -self } } + +impl Add for u8 { } +impl Sub for u8 { } +impl Mul for u8 { } +impl Div for u8 { } +impl Pow for u8 { } +impl Neg for u8 { }