The type checker implements subeffecting (a function with effects(IO) can be used where effects(IO, State<Int>) is expected) and forall<E> row variables are permissive (they match any concrete effect set), but full row-variable unification is not yet implemented.
Current behavior:
- Concrete effect sets type-check correctly via subeffecting
forall<E> row variables are accepted but not fully unified — they match anything without constraint propagation
What full row-variable unification would enable:
- Effect polymorphism: a function like
forall<E> fn map(fn(A -> B) effects(E), Array<A> -> Array<B>) effects(E) would propagate the callback's effects to the caller
- Effect set intersection and union constraints
Workaround: Use concrete effect sets in function signatures instead of relying on effect polymorphism.
The type checker implements subeffecting (a function with
effects(IO)can be used whereeffects(IO, State<Int>)is expected) andforall<E>row variables are permissive (they match any concrete effect set), but full row-variable unification is not yet implemented.Current behavior:
forall<E>row variables are accepted but not fully unified — they match anything without constraint propagationWhat full row-variable unification would enable:
forall<E> fn map(fn(A -> B) effects(E), Array<A> -> Array<B>) effects(E)would propagate the callback's effects to the callerWorkaround: Use concrete effect sets in function signatures instead of relying on effect polymorphism.