Description
The Option/Result combinators shipped in v0.0.89 (#211) have a type inference limitation: the type checker cannot infer the type variable T from a bare None or partial Err(...) constructor.
Affected calls
-- These fail to type-check:
option_unwrap_or(None, 99) -- T cannot be inferred from None
option_map(None, fn(@Int -> @Int) effects(pure) { @Int.0 + 1 })
-- These work:
option_unwrap_or(Some(42), 0) -- T=Int inferred from Some(42)
let @Option<Int> = None;
option_unwrap_or(@Option<Int>.0, 99) -- T=Int from typed binding
Root cause
Vera's type checker resolves generic type variables by inspecting argument types. Nullary constructors like None carry no type information — None is Option<T> for any T, but the checker has no mechanism to infer T from the remaining arguments or the expected return type.
This is a general limitation of Vera's current type inference (#55), not specific to combinators. It affects any generic function called with a bare nullary constructor.
Workaround
Bind the value to a typed slot first:
let @Option<Int> = None;
option_unwrap_or(@Option<Int>.0, 99)
Resolution
Full bidirectional type inference (#61) would propagate the expected type from the second argument or return context back to the first argument, resolving T without the explicit binding.
Description
The Option/Result combinators shipped in v0.0.89 (#211) have a type inference limitation: the type checker cannot infer the type variable
Tfrom a bareNoneor partialErr(...)constructor.Affected calls
Root cause
Vera's type checker resolves generic type variables by inspecting argument types. Nullary constructors like
Nonecarry no type information —NoneisOption<T>for anyT, but the checker has no mechanism to inferTfrom the remaining arguments or the expected return type.This is a general limitation of Vera's current type inference (#55), not specific to combinators. It affects any generic function called with a bare nullary constructor.
Workaround
Bind the value to a typed slot first:
Resolution
Full bidirectional type inference (#61) would propagate the expected type from the second argument or return context back to the first argument, resolving
Twithout the explicit binding.