3 ms·
Here's all the code from the parent in Rusty pseudosyntax: enum MyRecord { ConstructorName(Int, String, Bool) } enum TrafficLight { Re
by lalaithion 5y ago
Here's all the code from the parent in Rusty pseudosyntax:
enum MyRecord {
ConstructorName(Int, String, Bool)
}
enum TrafficLight {
Red,
Yellow,
Green
}
enum AST {
Integer(Int),
Boolean(Bool),
Addition(Ast, Ast),
Multiplication(Ast, Ast),
Equals(Ast, Ast),
Not(Ast)
}
`Not(Equals(Integer(1), Integer(2))) : AST`
enum IntErr {
Error(String),
IntResult(Int)
}
enum StringErr {
Error(String),
StringResult(String)
}
enum WithError<A> {
Error(String),
Result(A)
}
`Result(3) : WithError<Int>`
`Result(True) : WithError<Bool>`
enum Weird<A, B> {
IgnoreTheType(Int),
}
`Weird<String, Bool>`
`IgnoreTheType(1) : Weird<String, Bool>`
`IgnoreTheType(2) : Weird<Char, Float>`
`IgnoreTheType(3) : Weird<Bool, Double>`
`Addition(Boolean(True), Not(Integer(3)))`
enum AST<R> {
Integer(Int),
Boolean(Bool),
Addition(Ast<Int>, Ast<Int>),
Multiplication(Ast<Int>, Ast<Int>),
Equals(Ast<R>, Ast<R>),
Not(Ast<Bool>)
}
Finally, we get our GADT:
enum AST<R> {
Integer(Int) : Ast<Int>,
Boolean(Bool) : Ast<Bool>,
Addition(Ast<Int>, Ast<Int>) : Ast<Int>,
Multiplication(Ast<Int>, Ast<Int>) : Ast<Int>,
Equals(Ast<R>, Ast<R>) : Ast<Bool>,
Not(Ast<Bool>) : Ast<Bool>
}
- bradrn 5y agoThanks lalaithion! I don’t know Rust, so it’s interesting to see how different it is compared to Haskell. A question: how much of this would actually compile in Rust?
- deleted 5y ago[deleted]
- kaoD 5y ago- Assuming `Int` and `Bool` are user-defined types (Rust has `bool` and many types of ints like `usize`, `i64`, etc. instead). If you want to work over ANY primitive integer you can use the `num_traits` crate and make your type generic over `num_traits::PrimInt`, or even `num_integer::Integer` to include support for crates such as `num_bigint`. - Rust needs indirection for recursive data types (like the AST) using `Box`, references, or another kind of indirection. Otherwise, the size isn't known at compile time (since it's potentially infinite). - Rust doesn't have GADTs (yet?) so the last AST is purely theoretical. - `IgnoreTheType` (and `AST<R>`) would require explicit use of `PhantomData` for variants without `R` https://doc.rust-lang.org/std/marker/struct.PhantomData.html https://doc.rust-lang.org/std/marker/struct.PhantomData.html On Rust's playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=40b9ce0351c3adccd53cc6231c72d742 https://play.rust-lang.org/?version=stable&mode=debug&editio...
- bradrn 5y agoThank you! So it looks like most of my post does indeed work, except for the GADT itself. (Also, I had not known about Rust Playground, so thanks for introducing me to that too.)
- deleted 5y ago[deleted]