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
是否有意义。
我正在尝试通过实现自己的转换器来了解 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
是否有意义。