向函数动态添加约束

问题描述 投票:0回答:0

有什么方法可以动态地向类型类函数添加约束吗?

假设我的类型类采用类型函数

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  

我的类型定义如下,

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 

在我调用

traverseRecord
的地方,我传递的函数有一些额外的约束......因此我不能调用
traverseRecord

比方说,我正在调用我的函数,

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

上面的工作正常,但是如果我想改变

myTraverseFn
之类的,那就失败了

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)

由于额外的

Show a
约束而失败。

如果我将

Show a
添加到我的类型类中,它将正常工作......但我不想那样做...... 有什么办法可以以某种方式扩展类型类中定义的函数的约束吗?

就像我传递的函数具有类型类函数想要的所有约束,但它还有一些额外的约束。

我能理解编译器不确定我的约束,但我怎样才能让它工作?可能吗?

functional-programming purescript
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.