I've found the occasional want to do RowToList magic on a function that takes a record as an argument. The problem is these are inferred polymorphically, or at least the record tail is left unknown.
conjure ::
forall r rl z.
RowToList r rl =>
Conjure rl r =>
({ | r } -> z) -> z
conjure = ?conjure
example =
conjure \{ foo, bar } -> ...
Something like this doesn't compile because the type of r in this case will involve an unknown for the tail and RowToList requires an empty row terminator. Making this compile requires a type signature on the lambda closing the row. However, if we can conjure a record with only the required fields, this is totally safe.
Could we have something like
class Closed :: forall k. Row k -> Row k -> Constraint
class Closed open closed | open -> closed
Where the compiler yields a closed row with only the known components of the row? This would allow us to type the example as
conjure ::
forall r rl z.
Closed r r =>
RowToList r rl =>
Conjure rl r =>
({ | r } -> z) -> z
Forcing the unknown tail to unify with ().
I've found the occasional want to do
RowToListmagic on a function that takes a record as an argument. The problem is these are inferred polymorphically, or at least the record tail is left unknown.Something like this doesn't compile because the type of
rin this case will involve an unknown for the tail andRowToListrequires an empty row terminator. Making this compile requires a type signature on the lambda closing the row. However, if we can conjure a record with only the required fields, this is totally safe.Could we have something like
Where the compiler yields a closed row with only the known components of the row? This would allow us to type the example as
Forcing the unknown tail to unify with
().