What I’m trying to do is a little more specific than the title here, but the general idea is there.
Here’s some sample code to demonstrate the problem:
type FieldRow = (email :: String, p1 :: String, p2 :: String)
setValue :: ∀ sym r0 a t0 row
. IsSymbol sym
=> RowCons sym { value :: a | r0 } t0 row
=> SProxy sym
-> a
-> Record row
-> Record row
setValue sym = set $ prop sym <<< prop (SProxy :: SProxy "value")
updateValue :: Variant FieldRow -> (Record FieldRow -> Record FieldRow)
updateValue = match
{ p1: setValue (SProxy :: SProxy "p1")
, p2: setValue (SProxy :: SProxy "p2")
, email: setValue (SProxy :: SProxy "email")
}
setValue
is a helper function that given a SProxy
and a value, will produce a record update function for this particular structure. updateValue
will also produce a record update function, just given a Variant
. However we can see that for any given Variant
passed to updateValue
, all it does is call setValue
passing in the SProxy
corresponding to the label of the variant, and then it’s value. It seems like this could be accomplished without needing to explicitly write out every case of the Variant
.
After looking into the internals of purescript-variant, I attempted this:
updateValue_ :: ∀ a row => Variant row -> Record row -> Record row
updateValue_ v =
case coerceV v of
VariantRep r -> set (reifySymbol r.type prop) r.value
where
coerceV :: Variant row -> VariantRep a
coerceV = unsafeCoerce
Which is failing to build with the error:
Could not match contrained type
Strong t4 => t4 t5 t6 -> t4 { | t7 } { | t8 }
with type
(t0 -> t1) -> t2 -> t3
I’m guessing I’m missing something with the way to use reifySymbol
, because it apparently is correctly seeing that the type of the expression reifySymbol r.type prop
is Lens t7 t8 t4 t5
, but it’s not seeing it as a valid argument to pass to set
. Can anyone shed some light on what’s going on here, or if there are any glaring issues with this approach in general?