在下面的代码片段中,我最初认为有一个受限制的monad错误(我忘记在Monad m =>
定义中添加instance Monad (Transform m a)
了)。阅读了很多有关受限制的monad的知识后,我想知道为什么这里碰巧是可以的:
{-# LANGUAGE GADTs #-}
data Next a where
Todo :: a -> Next a
Done :: Next a
instance Functor Next where
fmap f Done = Done
fmap f (Todo a) = Todo (f a)
data Transform m a b = Monad m => Transform ( m(Next a) -> m(Next b) )
instance Functor (Transform m a) where
fmap f (Transform ta) = Transform tb where
tb ma = ta ma >>= return . (fmap f)
instance Applicative (Transform m a) where
pure = return
mf <*> ma = do
f <- mf
a <- ma
return (f a)
instance Monad m => Monad (Transform m a) where
return b = Transform (t b) where
t b _ = return $ Todo b
(Transform t) >>= f = Transform (\ma -> do
a <- ma
case a of
Done -> return Done
--Todo a' -> ...
)
该示例非常虚构,我删除了所有无关的位。 (当前的实际问题与this有关。)关键部分是Monad m
中的Transform
限制。
我不太清楚这与经常引用的规范Set
-mon-monad示例有什么不同,后者确实表现出受限的monad限制。
答案 0 :(得分:6)
Transform
不是受限制的monad。
查看Set
。 Set
在其一个自变量中是一元的,除了所述自变量需要为Ord
。也就是说,Set
是Hask子类别上的monad,其中所有对象都位于Ord
中。
但是Transform
首先不是monad。 Transform :: (* -> *) -> * -> * -> *
,但Monad
适用于* -> *
类型的事物(如果您要使用全分类论者,一般而言,单子是内爆者,应该大致使用k -> k
类型一些k
,但Transform
也不完全适合较宽的模板)。当Transform m a
是单子时,单子是m
。只要Transform m a
还是monad,m
就是整个Hask的monad。你看到区别了吗?给定Transform m a
的{{1}}适用于每种类型。但是我无法在空白处加上“ ___对存在的每种类型都可以操作的{Monad m
”,因为对Set
的参数使用限制是限制{{1 }}对单子输入的类型没有限制,但对组成它的一种类型有限制。
答案 1 :(得分:4)
我不太清楚这与经常被引用的典范的“按单声道设置”示例有什么不同,后者确实表现出受限的单声道限制。
这是不同的,因为约束不在最后一个类型参数上,后者在Monad
中有所不同。在Set
的情况下。