Is there any way I can add a constraint to a type class function dynamically?
Let's say my type class takes a function of type
type FieldTraverseFn :: Row Type -> (Type -> Type) -> Type
type FieldTraverseFn row m = forall sym a row'
. IsSymbol sym
=> Row.Cons sym a row' row
=> Proxy sym
-> m Unit
and my type class is defined like,
class TraverseRecord :: RL.RowList Type -> Row Type -> Row Type -> (Type -> Type) -> Constraint
class (Monad m) <= TraverseRecord rl row wholeRow m | rl -> row where
traverseRecord :: FieldTraverseFn wholeRow m
-> Proxy rl
-> Proxy wholeRow
-> m Unit
In the place where I'm calling traverseRecord the function that i'm passing has some additional constraint... because of it I can't call traverseRecord,
Let's say, I'm calling my function like,
logFields :: forall row wholeRow rl
. (RL.RowToList row rl)
=> TraverseRecord rl row row Effect
=> (Record row)
-> Effect Unit
logFields rec = traverseRecord myTraverseFn (Proxy :: Proxy rl) (Proxy :: Proxy row)
where
myTraverseFn = Debug.traceM <<< reflectSymbol
The above works fine, but if I want to change myTraverseFn like, it is failing
myTraverseFn :: forall sym a row'
. IsSymbol sym
=> Row.Cons sym a row' row
=> Show a
=> Proxy sym
-> Effect Unit
myTraverseFn pxy = do
let a = Record.get pxy rec
Debug.traceM $ (reflectSymbol pxy) <> (show a)
It is failing because of the additional Show a constraint.
If I add the Show a to my type class it will work fine... But I don't want to do that..
Is there any way I can extend the constraint of a function defined in type class in some way?
Like the function that I'm passing has all the constraint that the type class function wants but it has some additional constraint.
I can understand that the compiler isn't sure about my constraint, but How can I make it work? is it possible?