Haskell 哈斯克尔。如何使用GADT实现自定义monad转换器?
我试图通过实现我自己的monad transformers来学习monad。代码 如果我使用Haskell 哈斯克尔。如何使用GADT实现自定义monad转换器?,haskell,monad-transformers,Haskell,Monad Transformers,我试图通过实现我自己的monad transformers来学习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 ‘* -> *’
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
实例Monad m=>函子(DummyT m x y),其中
fmap=liftM
实例Monad m=>Applicative(DummyT m x y),其中
纯=返回
()=ap
实例Monad m=>Monad(DummyT m x y)其中
返回=返回
(>>=)=绑定
数据DummyT m x y z,其中
Return::z->DummyT m x y z
Bind::dummytmxyz->(z->dummytmxyq)->dummytmxyq
中的
m
的类型显然是*->*
,因为m
应用于类型
在
m
未使用,因此GHC推断种类*
,因为这是最简单的。也许它可以制造出这种多面体,但事实并非如此
如果您想要另一种,请明确要求:
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
是否有意义
m
的类型显然是*->*
,因为m
应用于类型
在
m
未使用,因此GHC推断种类*
,因为这是最简单的。也许它可以制造出这种多面体,但事实并非如此
如果您想要另一种,请明确要求:
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
是否有意义。*
正在慢慢地被遗忘。最好导入数据。进行分类
并使用类型
。谢谢,现在它可以编译了。你能解释一下为什么不需要m
吗?@datamoose你没有在Return
和Bind
类型中使用它,除了作为DummyT
的参数。在任何情况下,我们都不能像在newtype
定义中那样读取m(某些类型)
。@datamoose,我怀疑要使它成为monad转换器,您需要添加一个构造函数Lift::ma->DummyT m x y a
。最好首先重新排列类型参数:dummytxyma
。这将允许您编写实例MonadTrans(DummyT x y),其中lift=lift
*
正在缓慢匹配到遗忘状态。最好导入数据。进行分类
并使用类型
。谢谢,现在它可以编译了。你能解释一下为什么不需要m
吗?@datamoose你没有在Return
和Bind
类型中使用它,除了作为DummyT
的参数。在任何情况下,我们都不能像在newtype
定义中那样读取m(某些类型)
。@datamoose,我怀疑要使它成为monad转换器,您需要添加一个构造函数Lift::ma->DummyT m x y a
。最好首先重新排列类型参数:dummytxyma
。这将允许您编写实例MonadTrans(dummytxy),其中lift=lift
。
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