#monads #functor #monoid #applicative

kinder

Kinder 是一个小型 crate,它为常见的 Rust 结构添加代数结构,并模拟高阶类型

4 个版本

使用旧的 Rust 2015

0.1.3 2016 年 9 月 28 日
0.1.2 2016 年 9 月 20 日
0.1.1 2016 年 9 月 16 日
0.1.0 2016 年 9 月 16 日

#1882 in Rust 模式


functils 中使用

自定义许可

22KB
517

Kinder

Build Status

Rust 的代数结构和高阶类型模拟

Kinder 提供了一些工具和特性,这些是函数式程序员日常使用的。

Kinder 还在不断完善。目标是使高阶类型 (HOT) 对 Rust 程序员来说易于理解,并提供一系列宏,以尽可能使自定义 HOT 的实现变得简单。.

更新:将所有宏移动到 lift.rs 以便使用。

待办事项

  1. 完成 std::collections 的 Monad 实现

  2. 实现 std::collections 的 Applicative

  3. 实现 std::collections 的 Traversable(首先实现 Foldable)

  4. 开发使自定义类型轻松实现这些特性的宏

  5. 找出如何实现需要 Ord 或 Hash 的结构体的 Applicative(apply 方法是问题所在,例如有序函数是什么?)

提升模块

提升模块定义了 Higher 结构,允许创建高阶类型。它还导出宏 lift!,该宏为类型 * -> * 实现了 Higher。

半群模块

为 std::collections 以及 String 实现了 SemiGroup。提供了一个方法 add,它接收两个相同类型的项并返回相同类型的元素。

单子模块

为 std::collections 以及 String 实现了 Monoid。为半群提供了 id 方法,使得 x.add(T::id()) = x。

可折叠模块

为 std::collections 实现了 Foldable。提供了一个方法 foldr,它接收一个起始值和一个函数,并使用该函数折叠 Foldable。请参阅示例以获取更多信息。

函子模块

为 std::collections 实现了 Functor,并导出宏 functorize!,该宏使任何实现了 iter 的提升类型成为函子。

应用模块

为 std::collections 实现了 Applicative,并提供了两个方法。Raise 方法将 T 提升为 A,即 Vec::lift(1) = vec!(1)。Apply 方法接收一个应用和一个提升函数并将其应用,即 vec!(1,2).apply(vec!(|x| x+1, |x| x*x)) = vec!(2, 4)。

单子模块

为 std::collections 实现了 Monad。单子有两个函数,lift(通常是 return 但 return 在 Rust 中是保留的),和 bind。Lift 接收一个元素并将其“提升”到单子中,例如 Option::lift(2) = Some(2)。Bind 类似于 fmap,除了映射函数的类型为:A -> M 即 i32 -> Option。通常使用 flat_map 来实现 Bind。

示例:泛型求和向量

extern crate kinder;
use kinder::lift::{Foldable, Monoid};

fn sum_foldable<B: Monoid<A=B>, T: Foldable<A=B>>(xs : &T) -> B
{
  xs.foldr(B::id(), |x, y| x.add(y))
}

fn main() {
  let ints = vec!(1,2,3);
  let floats = vec!(1.0,2.0,3.0);
  let strings = vec!(String::from("Hello"), String::from(", "), String::from("World!"));
  println!("{}", sum_foldable(&ints)); //prints 6
  println!("{}", sum_foldable(&floats)); //prints 6
  println!("{}", sum_foldable(&strings)); //prints "Hello, World!"
}

使用以下命令运行此示例

cargo run --example fold-example

示例:泛型平方函数,归功于 /u/stevenportzer 在 Reddit 上的调试和使类型工作,使用以下命令运行

cargo run --example func-example
extern crate kinder;
use kinder::lift::Functor;
use std::ops::Mul;

fn squares<A: Mul<Output=A> + Clone, T: Functor<A, B=A, C=T>>(xs: &T) -> T {
  xs.fmap(|&x| x*x)
}

fn main() {
  prinln!("{:?}", squares(&vec!(1,2,3)));  //will print [1, 4, 9]
}

alt text

徽标来源

无运行时依赖