认为标准
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
)更漂亮。