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
Rust 的代数结构和高阶类型模拟
Kinder 提供了一些工具和特性,这些是函数式程序员日常使用的。
Kinder 还在不断完善。目标是使高阶类型 (HOT) 对 Rust 程序员来说易于理解,并提供一系列宏,以尽可能使自定义 HOT 的实现变得简单。.
更新:将所有宏移动到 lift.rs 以便使用。
待办事项
-
完成 std::collections 的 Monad 实现 -
实现 std::collections 的 Applicative -
实现 std::collections 的 Traversable(首先实现 Foldable)
-
开发使自定义类型轻松实现这些特性的宏
-
找出如何实现需要 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
示例:泛型求和向量
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]
}