Git Product home page Git Product logo

rust2fun's Introduction

rust2fun (pronounced: rʌstafʌn)

Crates.io docs.rs build

A library for functional programming in Rust.

Build

By default, the library is built with the std feature enabled. To disable it, use the --no-default-features flag.

Usage

Add this to your Cargo.toml:

[dependencies]
rust2fun = "0.2.1"

and import the prelude:

use rust2fun::prelude::*;

Supported features

Combinators:

Type classes:

Data types:

Examples

  1. Function print_user_credit_card accepts user(s) wrapped in any effect (Option, Result, Vec, etc.) and prints corresponding credit card(s).
fn get_credit_card(user: User) -> CreditCard {
    // Get credit card for user
}

fn print_credit_card(card: CreditCard) {
    // Print credit card details
}

fn print_credit_card_of<F>(user: F)
    where
        F: Functor<CreditCard, Param=User>,
        F::Target<CreditCard>: Functor<(), Param=CreditCard>,
{
    user.map(get_credit_card).map(print_credit_card);
}

...usage:

fn user(id: u32) -> Option<User> {
    // Get user from database
}

fn all_users() -> Vec<User> {
    // Get all users from database
}

print_credit_card_of(user(1));
print_credit_card_of(all_users());
  1. Validation accumulating all errors.

Assuming we have the following validation rules that need to be applied to create a new credit card:

fn validate_number(number: CreditCardNumber) -> ValidatedNev<CreditCardNumber, Error> {
    // Validating credit card number
}

fn validate_expiration(date: Date) -> ValidatedNev<Date, Error> {
    // Validating expiration date
}

fn validate_cvv(cvv: Code) -> ValidatedNev<Code, Error> {
    // Validating CVV code
}

...we can create a new credit card by applying all validation rules and collecting all errors in a vector Vec, non-empty vector NEVec (like in the example) or other semigroup (e.g. String, u32, etc.):

fn validate_credit_card(
    number: CreditCardNumber,
    expiration: Date,
    cvv: Code,
) -> ValidatedNev<CreditCard, Error> {
    ValidatedNev::pure(CreditCard::new)
        .ap3(validate_number(number),
             validate_expiration(expiration),
             validate_cvv(cvv))
}

...alternatively, this can be done using the map3 method:

fn validate_credit_card(
    number: CreditCardNumber,
    expiration: Date,
    cvv: Code,
) -> ValidatedNev<CreditCard, Error> { 
    MapN::map3(validate_number(number),
               validate_expiration(expiration),
               validate_cvv(cvv),
               CreditCard::new)
}
  1. bind! notation for monads (like do notation in Haskell or for comprehension in Scala):

Assuming we have the following functions defined:

fn get_opening_prices() -> Vec<(AssetId, i32)> {
  // Get opening prices from an external service
}

fn get_closing_prices() -> Vec<(AssetId, i32)> {
  // Get closing prices from an external service
}

fn get_asset_name(id: AssetId) -> Option<String> {
  // Recover asset name for the given id
}

...we can use bind! notation to calculate daily profit for each asset:

let profits: Vec<(String, i32)> = bind! {
    for (id_open, opening_price) in get_opening_prices();
    for (id_close, closing_price) in get_closing_prices();
    let diff = closing_price - opening_price;
    for name in OptionToVec.apply(get_asset_name(id_open)),
        if id_open == id_close && diff > 0;
    (name, diff)
};

Release notes

0.1.0 (2023-01-22)

  • Initial release: combinators, Semigroupal, Invariant, Functor, Apply, Applicative, FlatMap, Monad

0.2.0 (2023-09-10)

  • The project got its logo (thanks olasinitsyna)
  • Moved macros imports to the prelude
  • Added noopX and tupleX sets of functions
  • Added type classes: Semigroup, Monoid, Bifunctor + Higher2 (thanks lrind)
  • Added data types: NEVec, Validated
  • Added bind! notation
  • Multiple fixes and improvements

0.2.1 (2023-09-21)

  • Fixed Semigroupal and Apply behavior (thanks GoldsteinE for the report)
  • Added type classes: Pure, AndThen
  • Refactored mapX and apX functions

rust2fun's People

Contributors

k206i avatar kalaninja avatar lrind avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

thecaralice k206i

rust2fun's Issues

Fix implementation of Applicative

The current implementation of Apply:ap with apply_iter macro is incorrect.
Thanks @GoldsteinE for pointing this out:

λ => [(+1), (+2)] <*> [3, 4]
[4,5,5,6]

The suggested solution is to

  • remove apply_iter macro
  • implement a new macro apply_flatmap implementing ap method as self.flat_map(|f| fa.map(f)).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.