代码之家  ›  专栏  ›  技术社区  ›  yairchu

符号是否特定于“base:ghc.base.monad”?

  •  9
  • yairchu  · 技术社区  · 15 年前

    认为标准 Monad 类有缺陷,它实际上应该扩展 Functor Pointed 漂浮在周围。

    我并不一定声称这是正确的做法,但假设有人试图这么做:

    import Prelude hiding (Monad(..))
    
    class Functor m => Monad m where
        return :: a -> m a
        join :: m (m a) -> m a
        join = (>>= id)
        (>>=) :: m a -> (a -> m b) -> m b
        a >>= t = join (fmap t a)
        (>>) :: m a -> m b -> m b
        a >> b = a >>= const b
    

    到目前为止还不错,但是在尝试使用do符号时:

    whileM :: Monad m => m Bool -> m ()
    whileM iteration = do
        done <- iteration
        if done
            then return ()
            else whileM iteration
    

    编译器抱怨:

    Could not deduce (base:GHC.Base.Monad m) from the context (Monad m)
    

    问题:

    符号只适用于 base:GHC.Base.Monad ?有什么方法可以让它和其他方法一起工作吗 单子 班级?

    额外语境:

    我真正想做的是替换 base:Control.Arrow.Arrow 带有“广义” Arrow 班级:

    {-# LANGUAGE TypeFamilies #-}
    
    class Category a => Arrow a where
        type Pair a :: * -> * -> *
        arr :: (b -> c) -> a b c
        first :: a b c -> a (Pair a b d) (Pair a c d)
        second :: a b c -> a (Pair a d b) (Pair a d c)
        (***) :: a b c -> a b' c' -> a (Pair a b b') (Pair a c c')
        (&&&) :: a b c -> a b c' -> a b (Pair a c c')
    

    然后使用 箭头 的proc符号 箭头 类,但与上面的do notation和 单子 .

    我将主要使用 Either 作为我的对类型构造函数而不是 (,) 与当前类型相同的类型构造函数 箭头 班级。这可能使我的玩具RTS游戏的代码( cabal install DefendTheKind )更漂亮。

    1 回复  |  直到 15 年前
        1
  •  20
  •   C. A. McCann Ravikant Cherukuri    15 年前

    你需要使用 NoImplicitPrelude extension 对于完全可重新绑定的语法,包括 do proc . 在这种情况下,您可以得到以下内容:

    “do”符号是使用范围内的任何函数(>>=)、(>>)和fail(而不是序曲版本)翻译的。列表理解、MDO(第7.3.6节,_递归do符号_)和并行数组理解不受影响。

    您还可以调整对否定、相等、文字值和其他内容的一些处理。混淆代码的好方法!

    P.S.——如果您要重新绑定 语法, what sigfpe calls "parameterized monads" 非常有趣。同样的想法在 category-extras 在下面 Control.Monad.Indexed . 是的,它们确实使用可重新绑定的语法,尽管类型签名截然不同!