Adding Constraint Dynamically to a function

38 Views Asked by At

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?

0

There are 0 best solutions below