Warning: Some posts on this platform may contain adult material intended for mature audiences only. Viewer discretion is advised. By clicking ‘Continue’, you confirm that you are 18 years or older and consent to viewing explicit content.
The thing about Rust’s type inference that seems wild to anyone who hasn’t seen Hindley-Milner/ML style type systems before is that it’s “bidirectional” (in quotes because that’s not a proper type theory term as far as I know). The type of the left-side of an assignment can determine the type (and behavior!) of the right side. For instance, this is ambiguous:
The expression creates an iterator over the (letter, number) pairs, and collect() stores the elements in a newly created container. But which container type? Here are two valid variants:
The thing about Rust’s type inference that seems wild to anyone who hasn’t seen Hindley-Milner/ML style type systems before is that it’s “bidirectional” (in quotes because that’s not a proper type theory term as far as I know). The type of the left-side of an assignment can determine the type (and behavior!) of the right side. For instance, this is ambiguous:
let foo = [("a", 1), ("b", 2)].into_iter().collect();
The expression creates an iterator over the
(letter, number)
pairs, andcollect()
stores the elements in a newly created container. But which container type? Here are two valid variants:let foo: Vec<_> = [("a", 1), ("b", 2)].into_iter().collect();
This creates a vector with items
("a", 1)
and("b", 2)
.let foo: HashMap<_, _> = [("a", 1), ("b", 2)].into_iter().collect();
This creates a mapping where
"a"
and"b"
are keys, and1
and2
are the corresponding values.Playground link in case you’d like to mess with this concept: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=76f999f4db600415643b0c58c19c69b7