diff --git a/README.md b/README.md index 2309e20..631d447 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Maitar is a rust library providing some functional programming constructions like: +- Semigroup, +- Monoid, - Functor, - Applicative; - Bind and @@ -12,8 +14,9 @@ Some incarnations are available like: - Option, - Result, - Either -- Vector and -- Reader +- Vector, +- Reader and +- Writer. # Philosophy diff --git a/src/specs/mod.rs b/src/specs/mod.rs index ab75467..53cd9ae 100644 --- a/src/specs/mod.rs +++ b/src/specs/mod.rs @@ -8,3 +8,5 @@ pub mod applicative; pub mod bind; pub mod functor; pub mod monad; +pub mod monoid; +pub mod semigroup; diff --git a/src/specs/monoid.rs b/src/specs/monoid.rs new file mode 100644 index 0000000..20cedd1 --- /dev/null +++ b/src/specs/monoid.rs @@ -0,0 +1,11 @@ +/* + * MIT License + * + * Copyright (c) 2023 Didier Plaindoux + */ + +use crate::specs::semigroup::Semigroup; + +pub trait Monoid: Semigroup { + fn neutral() -> Self::T; +} diff --git a/src/specs/semigroup.rs b/src/specs/semigroup.rs new file mode 100644 index 0000000..e9f8e56 --- /dev/null +++ b/src/specs/semigroup.rs @@ -0,0 +1,10 @@ +/* + * MIT License + * + * Copyright (c) 2023 Didier Plaindoux + */ + +pub trait Semigroup { + type T; + fn compose(a: Self::T, b: Self::T) -> Self::T; +} diff --git a/src/standard/writer.rs b/src/standard/writer.rs index f824427..e2af7ef 100644 --- a/src/standard/writer.rs +++ b/src/standard/writer.rs @@ -5,7 +5,9 @@ */ use crate::core::hkp::HKP; +use crate::specs::applicative::Applicative; use crate::specs::functor::Functor; +use crate::specs::monoid::Monoid; use std::marker::PhantomData; pub struct Writer<'a, E: 'a, F: HKP<'a>, A: 'a>(F::T<(A, E)>); @@ -25,3 +27,17 @@ impl<'e, E, F: Functor<'e>> Functor<'e> for WriterK<'e, E, F> { Writer(F::map(move |(a, e)| (f(a), e), va)) } } + +impl<'e, E: Monoid, F: Applicative<'e>> Applicative<'e> for WriterK<'e, E, F> { + fn pure(a: A) -> Self::T { + Writer(F::pure((a, E::neutral()))) + } + + fn apply(mf: Self::T, ma: Self::T) -> Self::T + where + A: Clone, + MAP: Fn(A) -> B, + { + todo!() + } +}