Haskell。如何使用 GADT 实现自定义 monad 转换器?

Haskell. How to implement a custom monad transformer using GADT?

我正在尝试通过实现自己的转换器来了解 monad 转换器。代码 如果我使用 newType DummyT m x y z = DummyT { runDummyT :: m (Dummy x y z) } 编译 但如果我使用 GADT 则不会。但是我需要使用 GADT 但它似乎更多 难的。我收到此错误:

Expecting one more argument to ‘m’   
Expected a type, but ‘m’ has kind ‘* -> *’                                              
In the first argument of ‘DummyT’, namely ‘m’                                          
In the first argument of ‘Functor’, namely ‘(DummyT m x y)`

我在 applicative 和 monad 实例中遇到了同样的错误。 为什么会出现此错误?感谢任何帮助。

我的单子:

instance Monad (Dummy x y) where
  return = Return
  (>>=) = Bind

data Dummy x y z where
  Return :: z -> Dummy x y z
  Bind :: Dummy x y z -> (z -> Dummy x y q) -> Dummy x y q

变形尝试:

instance Monad m => Functor (DummyT m x y) where
  fmap = liftM

instance Monad m => Applicative (DummyT m x y) where
  pure = return
  (<*>) = ap

instance Monad m => Monad (DummyT m x y) where
  return = Return
  (>>=) = Bind

data DummyT m x y z where
  Return :: z -> DummyT m x y z
  Bind :: DummyT m x y z -> (z -> DummyT m x y q) -> DummyT m x y q

newType DummyT m x y z = DummyT { runDummyT :: m (Dummy x y z) }

m 的种类显然是 * -> * 因为 m 应用于类型。

data DummyT m x y z where
  Return :: z -> DummyT m x y z
  Bind :: DummyT m x y z -> (z -> DummyT m x y q) -> DummyT m x y q

m 未被使用,因此 GHC 推断种类 *,因为这是最简单的。它本可以做到这一点 poly-kinded,也许,但没有。

如果您想要另一种,请明确要求:

data DummyT (m :: * -> *) x y z where
  Return :: z -> DummyT m x y z
  Bind :: DummyT m x y z -> (z -> DummyT m x y q) -> DummyT m x y q

我想知道,如果不在这里使用 m 是否有意义。