Introduction

Rustica brings powerful abstractions from category theory and functional programming to the Rust ecosystem, providing a rich set of type classes, data types, and utilities commonly found in functional programming languages.

Getting Started

Add Rustica to your Cargo.toml:

[dependencies]
rustica = "0.7.1"

Optional Features

Async Support

[dependencies]
rustica = { version = "0.7.1", features = ["async"] }

Persistent Vectors

[dependencies]
rustica = { version = "0.7.1", features = ["pvec"] }

Then import the prelude in your Rust code:

use rustica::prelude::*;

Features

Type Classes

  • Functor, Applicative, Monad
  • Semigroup, Monoid
  • Traversable, Foldable
  • Bifunctor, Comonad

Data Types

  • Maybe<T>, Either<L, R>
  • IO<A>, State<S, A>
  • Reader<E, A>, Writer<W, A>
  • Cont<R, A>, AsyncMonad<A>

Transformers

  • StateT<S, M, A>
  • ReaderT<E, M, A>
  • WriterT<W, M, A>
  • Bidirectional conversion

Optics

  • Lens and Prism
  • IsoLens and IsoPrism
  • Composable and type-safe
  • Lawful implementations

Example: Identity Monad

use rustica::prelude::*;
use rustica::datatypes::id::Id;
use rustica::traits::identity::Identity;

// Create Id values
let x = Id::new(5);
let y = Id::new(3);
let z = Id::new(2);

// Access the inner value
assert_eq!(*x.value(), 5);

// Map over the value
let doubled = x.fmap(|n| n * 2);
assert_eq!(*doubled.value(), 10);

// Chain computations
let result = x.and_then(|a| 
    y.and_then(move |b| 
        z.fmap(move |c| a + b + c)
    )
);

assert_eq!(*result.value(), 10); // 5 + 3 + 2