代码之家  ›  专栏  ›  技术社区  ›  trpnd

如何定义由两个任意单声道变压器组成的单声道变压器?

  •  1
  • trpnd  · 技术社区  · 2 年前

    我想写一些类似于以下的东西:

    newtype FooT c d m a = FooT { unFooT :: (c (d m)) a }
    
    instance (MonadTrans c, MonadTrans d) => MonadTrans (FooT c d) where
      lift = FooT . lift . lift
    

    但是,此代码段不会编译:

    Could not deduce (Monad (d m)) arising from a use of ‘lift’
    

    我理解为什么这不会被编译;我们不知道任意变压器的应用 d m 它本身就是单子。然而,我不确定最好的方法是什么。 有没有一种干净的方法可以让这样的事情成功?如果我能在这条直线上添加一个约束条件,它大概会通过 Monad (d m) 在实例声明的左侧,但我不知道如何执行 m 不受约束。

    1 回复  |  直到 2 年前
        1
  •  1
  •   HTNW    2 年前

    QuantifiedConstraints GHC分机,这里是

    {-# LANGUAGE QuantifiedConstraints #-}
    
    instance (MonadTrans c, MonadTrans d, forall m. Monad m => Monad (d m)) =>
             MonadTrans (FooT c d) where
      lift = FooT . lift . lift
    

    m 在约束中是不一样的 M 比如 lift .量化的约束只意味着它所说的(“对任何人而言”) m :: Type -> Type 如果 Monad m 要求 Monad (d m) 是的,在 举起 这个通用语句正在用特定的 M 作为论据传递给 举起 因此 举起 是的 M 并没有脱离它的范围。