Comments 1
fn test_is_nat<T: Nat>() -> () {} fn main() { test_is_nat::<_0>(); test_is_nat::<_1>(); test_is_nat::<_2>(); // ... }
Вызывать эти функции несколько избыточно, для проверки типов достаточно их инстанцировать:
fn test_is_nat<T: Nat>() -> () {}
fn main() {
test_is_nat::<_0>;
test_is_nat::<_1>;
test_is_nat::<_2>;
// ...
}Now to check whether<is holdingholds for some typesAandBwe could use ourProofLtstruct to summonLttrait implementations, but in order to do this we need to define some method on theLttrait we could call. In case a method is found and compilation succeeds we can conclude thatLtis implemented for that pair for types, thus<property holds, otherwise it doesn't.
Это и несколько избыточно, и ненадёжно: перед каждым реальным использованием нужно вызывать ничего не делающий метод для того, чтобы зафорсить проверку типов. Проще это требование поместить непосредственно на определение ProofLt, благо Rust это позволяет:
struct ProofLt<A: Nat, B: Nat>(A, B)
where
Self: Lt<A, B>;С таким определением создать невалидное значение доказательства попросту невозможно.
trait Lt<A: Nat, B: Nat> { fn check() -> () {} }
Стрелка после списка параметров избыточна, если тип возвращаемого значения функции не указан, то он считается ().
<shameless_plug> Более продвинутую демонстрацию type-level программирования на Rust можно посмотреть в моей статье: https://habr.com/ru/post/578198 </shameless_plug>
Sign up to leave a comment.
Proof's by induction using Rust's type-system