4个稳定版本
2.0.0 | 2022年6月2日 |
---|---|
1.0.3 | 2022年5月20日 |
1.0.2 | 2022年5月18日 |
1.0.1 | 2022年5月17日 |
#905 在 编程语言
19KB
397 行
简单、可直接使用的SmallF*ck神秘语言的类型实现。高度受这篇文章的启发。
use typed_sf::*;
type SetTrue<Next = EOF> = Cycle<Flip, Flip<Next>>;
// [*<<[*]*>>>] // Move any-sized chunk of True's 2 cells left
#[allow(non_camel_case_types)]
type prog = Cycle<Flip<Left<Left<SetTrue<Right<Right<Right>>>>>>>;
#[allow(non_camel_case_types)]
type result = Run<
prog,
State<Nil, True, Cons<True, Nil>>
>;
assert_eq!(
<result as StateTrait>::val(),
(vec![true, true, false, false], false, Vec::new())
);
链接
Github仓库: https://github.com/Zote-the-Mighty-4o2/typed-sf.rs
文档: https://docs.rs/typed-sf/
lib.rs
:
类型级别的SF实现。证明类型系统是图灵完备的。高度受这篇文章的启发。
特性
typed-sf
支持“no_std”特性,但有局限性。List
和[State
][StateTrait]的运行时表示不可用(它们使用[Vec
]来表示自己)。
不支持特性的完整列表
- [
List::val()
](包括[Nil
]和Cons
)。 RuntimeState
.- [
StateTrait::val()
](包括State
和DefaultState
)。
还有一个“require_docs”特性,禁止未记录的pub
项。如果您想贡献,请随意关闭此默认特性。
工作原理
首先,有一些我称之为类型枚举的特质([Bit
],List
)。看看它
enum Bit {
True,
False
}
impl Bit {
fn neg(self) -> Bit {
match self {
Bit::True => Bit::False,
Bit::False => Bit::True
}
}
}
assert_eq!(Bit::True, Bit::False.neg());
assert_eq!(Bit::False, Bit::True.neg());
trait Bit {
type Neg: Bit;
fn real() -> bool;
}
struct True;
struct False;
impl Bit for True {
type Neg = False;
fn real() -> bool { true }
}
impl Bit for False {
type Neg = True;
fn real() -> bool { false }
}
assert_eq!(True::real(), <False as Bit>::Neg::real());
assert_eq!(False::real(), <True as Bit>::Neg::real());
当然,更多的是样板代码,但编译器也帮我们在编译时解决类型等式,而不是在运行时匹配。
为了类型化函数,我使用如下方式
#
// A and B are arguments to 'function'.
trait Call<A, B> { type Return; }
struct Sum;
struct Diff;
impl<A, B> Call<A, B> for Sum
where
A: Add<B>
{
type Return = <A as Add<B>>::Output;
}
impl<A, B> Call<A, B> for Diff
where
A: Sub<B>
{
type Return = <A as Sub<B>>::Output;
}
type Apply<A, Fn, B> = <Fn as Call<A, B>>::Return;
我们稍后可以用作
#
struct X;
struct Y;
struct XaddY;
struct XsubY;
impl Add<Y> for X {
type Output = XaddY;
}
impl Sub<Y> for X {
type Output = XsubY;
}
/* Add `::val() -> Self` function to all types...