Type of empty matrix in Rust
Let’s talk about two dimensional matrices in Rust. To be precise, two-dimensional matrices written as nested arrays.
A simple 2x2 matrix is looks like this:
let matrix = [[1, 2], [3, 4]];
A simple 1x1 matrix looks like this:
let matrix = [[1]];
The empty (0x0) matrix is…
let matrix = [[]];
Is it so? Let’s think together. For 0x0 we need to have matrix.len()
to be 0. But our ‘outer’ array has length of 1.
So we need to convert it to …
let matrix = [];
But this is one-dimensional array!
And if you try to compile it, Rust will complain:
Which is, actually, incorrect, because of ‘error[E0658]: using `_` for array lengths is unstable
’. It looks like a bug in Clippy.
Anyway, the proper type is [[i32;0];0]
:
let matrix: [[i32;0];0] = [];
Which is blowing my mind. It’s completely sound: we need to specify to inner type for the array.
But it’s still blow my mind. If it was foo:[i32;0] = []
no one would complain about specifying a type for an absent element.
But we need to specify inner type for absent value of array type. It’s an empty array of empty arrays of type i32
. Huh.
It’s like saying that 3 ≡ {{}, {{}}, {{}, {{}}}}
, if you get the joke. Nope, it’s even emptier than that. It’s like saying that 3 ≡ {{{{}}}}
. Is it smells of λs here?
The second thing which strikes me, is that we have the singular value for the empty 0x0 array, because only []
is possible value for the type [[i32;0];0]
.
I become math-immune compromised person, because it smells Zermelo. Or it’s Fraenkel? Actually, no, it’s even more funnier, because I can declare 0≡[]
, and 1≡[]
, and 2≡[]
, and 3≡[]
, and all of them would be differently typed []
, because of:
let zero: [i32;0] = [];
let one: [[i32;0];0] = [];
let two: [[[i32;0];0];0] = [];
let three: [[[[i32;0];0];0];0] = [];
Unfortunately, we can’t do math… Or can we? Some kind of recursion? I believe it’s not possible with lambdas, and any function would require signatures which can work with const generics, but not with ‘recursion depth’.
let sum = (|A, B|{[]})(one, two);
Nope, we can’t. Rust can’t deduce type for three… I gave up.
May be someone will pick up the banner and solve the challenge.