unison/unison-src/transcripts-using-base/fix2158-1.output.md

1.3 KiB

This transcript tests an ability check failure regression.

structural ability Async t g where
  fork : '{Async t g, g} a -> t a
  await : t a -> a

Async.parMap : (a ->{Async t g, g} b) -> [a] ->{Async t g} [b]
Async.parMap f as = 
  tasks = List.map (a -> fork '(f a)) as 
  List.map await tasks

  Loading changes detected in scratch.u.

  I found and typechecked these definitions in scratch.u. If you
  do an `add` or `update`, here's how your codebase would
  change:
  
    ⍟ These new definitions are ok to `add`:
    
      structural ability Async t g
      Async.parMap : (a ->{g, Async t g} b)
                     -> [a]
                     ->{Async t g} [b]

The issue was that certain ability processing was happing in less optimal order. g appears both as an ability used and as a parameter to Async. However, the latter occurrence is more strict. Unifying the types Async t g1 and Async t g2 requires g1 and g2 to be equal, while abilities that occur directly in a row are subject to some subtyping.

However, the ability handling was just processing rows in whatever order they occurred, and during inference it happened that g occurred in the row before `Async t g. Processing the stricter parts first is better, becauase it can solve things more precisely and avoid ambiguities relating to subtyping.