#esolang #typed #language #esoteric #sf #left #small-f-ck

no-std typed-sf

在Rust中实现SmallF*ck语言类型的可用实现

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编程语言

MIT 许可证

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]来表示自己)。

不支持特性的完整列表

还有一个“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... 

无运行时依赖

特性