yai*_*chu 9 monads haskell ghc
认为标准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
Run Code Online (Sandbox Code Playgroud)
到目前为止一切顺利,但在尝试使用do-notation时:
whileM :: Monad m => m Bool -> m ()
whileM iteration = do
done <- iteration
if done
then return ()
else whileM iteration
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
Could not deduce (base:GHC.Base.Monad m) from the context (Monad m)
Run Code Online (Sandbox Code Playgroud)
题:
do-notation仅适用于base:GHC.Base.Monad?有没有办法让它与另类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')
Run Code Online (Sandbox Code Playgroud)
然后在Arrow我的Arrow类中使用's proc-notation ,但是在上面的do-notation例子中失败了Monad.
我将主要Either用作我的对类型构造函数,而不是(,)当前Arrow类的类型构造函数.这可能会使我的玩具RTS游戏(cabal install DefendTheKind)的代码更漂亮.
C. *_*ann 20
您需要使用NoImplicitPrelude扩展来获得完全可重新绑定的语法,包括do和proc.在这种情况下,您可以获得以下内容:
"Do"符号使用任何函数(>> =),(>>)进行转换,并且失败,在范围内(不是Prelude版本).列表推导,mdo(第7.3.6节"递归标记")和并行数组推导不受影响.
您还可以调整一些否定,相等,字面值和诸如此类的处理.混淆代码的好方法!
ps - 如果要重新绑定do语法,sigfpe称之为"参数化monad"非常有趣.同样的想法是在提供category-extras下Control.Monad.Indexed.是的,他们确实使用可重新绑定的语法,尽管类型签名截然不同!