purescript/purescript-record

simple function doesn't typecheck

martyall opened this issue · 4 comments

Can someone tell me why this simple function

singleton :: forall s a r. IsSymbol s => RowCons s a () r => SProxy s -> a -> Record r
singleton s a = insert s a {}

produces the following error, which seems like it's coming from the RowLacking constraint that should be trivially satisfied

  No type class instance was found for

    Prim.RowCons s4
                 Entry
                 ()
                 t5

  The instance head contains unknown type variables. Consider adding a type annotation.

while applying a function insert
  of type IsSymbol t0 => RowLacks t0 t1 => RowCons t0 t2 t1 t3 => SProxy t0 -> t2 -> { | t1 } -> { | t3 }
  to argument s
while inferring the type of insert s
in value declaration singleton

where s4 is a rigid type variable
      t2 is an unknown type
      t0 is an unknown type
      t3 is an unknown type
      t1 is an unknown type
      t5 is an unknown type

You need to have RowLacks to insert into a record. I don't know much about why the constraints don't come together to tell you that's the thing that's missing, but generally Entry is a good indicator that some constraint is missing.

paf31 commented

It works for me if I add a RowLacks s () constraint, but that should be solvable now, as I understand it. @LiamGoodacre Any thoughts on this one?

paf31 commented

Oh I see why this is. s is not a type-level string in RowLacks s (), which becomes RowCons s Entry () x, which is then not solved for any concrete row x, so we have to propagate the constraint. It seems counter-intuitive, but this is why it's necessary to add the constraint.