在下面的代码片段中,我最初认为是受限制的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。

查看SetSet在其一个参数中是monadic,除了所述参数需要为Ord。也就是说,Set是Hask子类别上的monad,其中所有对象都在Ord中。

但是Transform首先不是monad。 Transform :: (* -> *) -> * -> * -> *,但是Monad适用于* -> *类型的东西(如果您要使用完整类别理论家,通常monads是enduncunctors,对于某些k -> k来说应该大致具有k类型,但Transform也不真正适合那个较宽的模板)。当Transform m a是monad时,是monad的东西就是mTransform 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/

10-14 19:11