Skip to content

Rust library providing some functional programming idioms

License

Notifications You must be signed in to change notification settings

Smallibs/maitar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Maitar

Maitar is a rust library providing some functional programming constructions like:

  • Semigroup,
  • Monoid,
  • Functor,
  • Applicative;
  • Bind and
  • Monad

Some incarnations are available like:

  • Identity,
  • Option,
  • Result,
  • Either
  • Vector,
  • Reader and
  • Writer.

Note: The curried version is not optimal since it relies on Boxed polymorphic functions and then dynamic dispatch.

Philosophy

In Rust, we can specify abstract types in a trait, i.e. Higher-Kinded Polymorphism (HKP for short). Therefore, such types are inhabited by trait implementations.

HKP

We propose a simple basic trait HKP where an abstract type T is defined. An essential remark about this type is its capability to accept a parametric type. This is important if we want to propose constructions coming from the category theory.

pub trait HKP {
    type T<A>;
}

Functor specification

The functional approach has been chosen to prohibit the use of self. There is no specific relationship between the structure that will implement the trait and the implementation of the trait.

use crate::core::hkp::HKP;

pub trait Functor: HKP {
    fn map<A, B, MAP>(f: MAP, ma: Self::T<A>) -> Self::T<B>
        where
            MAP: Fn(A) -> B;
}

Infix trait

The Infix trait provides the capability to use data with the Rust idiomatic approach thanks to the self first method parameter.

pub mod infix {
    use crate::specs::functor::Functor as Api;

    pub trait Functor<A> {
        type This: Api;
        type T<B>: Functor<B>;

        fn hkp_to_self<B>(a: <Self::This as HKP>::T<B>) -> Self::T<B>;

        fn self_to_hkp(self) -> <Self::This as HKP>::T<A>;

        fn map<B, MAP>(self, f: MAP) -> Self::T<B>
            where
                MAP: Fn(A) -> B,
                Self: Sized,
        {
            Self::hkp_to_self(Self::This::map(f, self.to_hkp()))
        }
    }
}

Functor usage

fn generalized_increment<F: Functor>(ma: F::T<i32>) -> F::T<i32> {
    F::map(|a| a + 1, ma)
}

Functor implementation

Implementation requires an initial definition of the basic structure. This can be seen as the ability to use or open one type of module, and nothing else. For Option we introduce OptionK and this one should implement HKP.

pub struct OptionK;

impl HKP for OptionK {
    type T<A> = Option<A>;
}

Then we can implement Option functor using the underlying map implementation.

impl Functor for OptionK {
    fn map<A, B, MAP>(f: MAP, ma: Self::T<A>) -> Self::T<B>
        where
            MAP: Fn(A) -> B,
    {
        ma.map(f)
    }
}

Infix implementation

impl<A> Functor<A> for Option<A> {
    type This = OptionK;
    type T<B> = Option<B>;

    fn from_hkp<B>(a: <Self::This as HKP>::T<B>) -> Self::T<B> {
        a
    }

    fn to_hkp(self) -> <Self::This as HKP>::T<A> {
        self
    }
}

Note: In reality, such material is done once per implementation thanks to the Transform trait.

Why Maitar?

See Maitar definition for more information. Composition is the main idea behind this word.

Other approaches and propositions

License

MIT License

Copyright (c) 2023-2024 Didier Plaindoux

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Releases

No releases published

Packages

No packages published

Languages