为什么这不是受限制的monad限制的情况?

时间:2018-07-05 06:41:40

标签: haskell monads ghc

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

2 个答案:

答案 0 :(得分:6)

Transform不是受限制的monad。

查看SetSet在其一个自变量中是一元的,除了所述自变量需要为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的情况下。