在下面的代码片段中,我最初认为是受限制的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
-as-a-monad示例有什么不同,该示例确实表现出受限的monad限制。 最佳答案
Transform
不是受限制的monad。
查看Set
。 Set
在其一个参数中是monadic,除了所述参数需要为Ord
。也就是说,Set
是Hask子类别上的monad,其中所有对象都在Ord
中。
但是Transform
首先不是monad。 Transform :: (* -> *) -> * -> * -> *
,但是Monad
适用于* -> *
类型的东西(如果您要使用完整类别理论家,通常monads是enduncunctors,对于某些k -> k
来说应该大致具有k
类型,但Transform
也不真正适合那个较宽的模板)。当Transform m a
是monad时,是monad的东西就是m
。 Transform m a
在所有Hask上都是monad,只要m
也是monad。你看到区别了吗?给定的Transform m a
Monad m
可对每种类型进行操作。但是我没有什么可以让“给定的___可以操作的Set
”空白的,因为Set
是单子(monad)形式的参数受到了限制,而Transform m a
对它的类型没有限制。 monadic,但组成它的类型之一。
关于haskell - 为什么这不是受限制的monad限制的情况?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51184809/