百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
T

tyrade

> 编程语言
开源

Rust 中用于类型级编程的纯函数语言

344 stars0 点赞0 次浏览
访问官网GitHub

工具介绍

Rust 中用于类型级编程的纯函数语言

Tyrade: a pure functional language for type-level programming in Rust

  • Motivating example: security types
  • More complex example: session and list types
  • How does Tyrade work?
  • Next steps

Tyrade is a proof-of-concept language showing how Rust traits enable a general-purpose type-level programming model. Its goal is to show that type-level programming is possible for useful tasks (not just writing Turing machines), and that programs can be written in a reasonable way. Here's what the language looks like:

tyrade! {
  // A type-level enum for Peano numerals, with "Z" (zero) and "S(n)" (successor).
  enum TNum {
    Z,
    S(TNum)
  }

  // A function that adds two Peano numerals together.
  fn TAdd() {
    match N1 {
      Z => N2,
      S(N3) => TAdd(N3, S(N2))
    }
  }
}

fn num_tests() {
  // 1 + 1 == 2
  assert_type_eq::>, TAdd, S>>();
}

At its core, Tyrade supports recursive enums and pure recursive functions. For the main ideas behind Tyrade, continue below or consider reading my blog post on type-level programming:

Motivating example: security types

Others have shown that Rust traits are Turing-complete and can be used for e.g. Fizz-Buzz. However, the direct expression of type-level programs in traits is quite obtuse, i.e. the relationship between the conceptual program and the actual traits is hard to see.

As a simple example, consider two types HighSec and LowSec representing the security of an item:

struct High;
struct Low;

struct Item {
  t: T,
  _sec: PhantomData
}

A simple type-level program is to compute the maximum of two security levels S1 and S2. That is, if S1 = S2 = Low, then return Low, else return High. To encode this program in Rust traits, we turn the MaxLevel function into a trait, with an impl for each condition.

trait ComputeMaxLevel {
  type Output;
}

// These impls define the core computation
impl ComputeMaxLevel  for Low  { type Output = Low;  }
impl ComputeMaxLevel for Low  { type Output = High; }
impl ComputeMaxLevel  for High { type Output = High; }
impl ComputeMaxLevel for High { type Output = High; }

// The type alias gives us a more convenient way to "call" the type operator
type MaxLevel = >::Output;

fn sec_tests() {
  // example unit tests
  assert_type_eq::>();
  assert_type_eq::>();
}

The goal of Tyrade is to perform this translation automatically from a functional programming model. Using Tyrade, this program is written as:

tyrade!{
  enum Security {
    Low,
    High
  }

  fn MaxLevel() {
    match S1 {
      Low => match S2 {
        Low => Low,
        High => High
      }
      High => High
    }
  }

  // In the high-level language, we can more easily see a chance for simplification.
  fn MaxLevel2() {
    match S1 {
      Low => S2,
      High => High
    }
  }
}

This way, both the type definition and the type-level program are expressed using familiar constructs like fn, enum, and match.

More complex example: session and list types

Tyrade can be used to define a framework for communication protocols, e.g. session types. For example, the session types and their duals can be defined as follows:

…

Tyrade provides a standard library of type-level building blocks like booleans, numbers, and lists. For example, we can use lists to implement the compile-time saving and indexing of jump points in session types.

…

How does Tyrade work?

Consider the translation of TAdd. Here's the Tyrade definition:

fn TAdd() {
  match N1 {
    Z => N2,
    S(N3) => TAdd(N3, S(N2))
  }
}

And here's the generated Rust code:

pub trait ComputeTAdd {
    type Output;
}

pub type TAdd = >::Output;

impl ComputeTAdd for Z {
    type Output = N2;
}

impl ComputeTAdd for S
where
    N3: ComputeTAdd>
{
    type Output = TAdd>;
}

At a high level, Tyrade does the following for you:

  1. The compiler sets up the necessary traits and type definitions (ComputeTAdd and TAdd).
  2. While compiling the operators to types, all operations are added as where constraints. For example, TAdd(N3, S(N2)) creates the constraint N3: ComputeTAdd>.
  3. The compiler generates a different impl for each match branch. In the case of multiple matches, e.g. as in MaxLevel, the compiler generates an impl for the cartesian product of all match branches.

See trans.rs for the details.

Next steps

Tyrade is experimental, meaning I'm still discovering the boundaries of what's possible. There are two main areas of inquiry:

  1. What type-language mechanisms does Rust's trait system permit? For example, I was not able to implement == since type equality in Rust doesn't quite work as we need it. Higher-kinded types would be useful as well to enable proper polymorphic type functions.

  2. What application areas can benefit from a type-level programming language? Session types are the most complex example I've seen so far, but I'd be really interested to find other use cases for Tyrade.

Please let me know if you'd be interested in using or contributing to Tyrade! Email me at [email protected].

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

Rust

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月18日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言