Hi everyone!
Couldn’t find a question around this so hope this isn’ta duplicate.
I’d like to be able to:
mergeRecord :: forall r. {a :: String | r} -> {a :: String, b :: String | r}
mergeRecord x = Record.merge { b: "hi" } x
Is this possible? I keep getting:
No type class instance was found for
Prim.Row.Nub ( a :: String
, b :: String
| r4
)
( a :: String
, b :: String
| r4
)
I thought maybe adding
Prim.Row.Nub () r =>
would help but obviously didn’t. Was this at all in the right direction?
Thanks for the help and pardon the noobness 
merge
maintains the invariant that there are no duplicate labels in the row via Nub
. With the signature as-is, there’s no way for it to know that r
does not also contain b
itself. As an example, lets consider what would happen if there was no Nub
ing (which you can get by replacing merge
with union
):
mergeRecord { a: "hello", b: 42 } -- b is Int
This would yield the result type of
{ a :: String, b :: String, b :: Int }
Since the input record already contains a b
. However, what you actually want is for it to remove the existing b
, and replace it with yours. Nub
is a constraint that will do that, it only keeps the first occurrence of a label. But since r
is a forall
quantified variable, you will need to propagate the Nub
constraint so it can compute the nubbed row.
Considering your type signature has an a
label in it, I assume this is a reduction and your real code actually needs to assume the presence of that. You probably want something like:
mergeRecord ::
forall rin rout.
Nub (a :: String, b :: String | rin) rout =>
{ a :: String | rin } ->
{ | rout }
mergeRecord x = Record.merge { b: "hi" <> x.a } x
This separates the input and output arguments, otherwise the constraint will restrict you to passing in only records that do not contain b
. If that is what you want, I suggest using disjointUnion
instead.
7 Likes
Nate! Dude, you rock. Thanks!
1 Like
You’re right that I was looking for disjointUnion.
That’s great to get some clarification around that; appreciate the help. Cheers mate