是否存在一个渐近优化MonadPlus操作序列的Codensity MonadPlus?

时间:2015-08-27 14:35:51

标签: haskell monads category-theory free-monad

最近有关于DList< - >之间关系的question[]Codensity< - > Free

这让我想到MonadPlus是否有这样的事情。 Codensity monad仅针对monadic操作改进了渐近性能,而不是mplus

此外,虽然曾经有Control.MonadPlus.Free,但FreeT f []支持MonadPlus。由于没有明确的免费improvePlus :: Functor f => (forall m. (MonadFree f m, MonadPlus m) => m a) -> FreeT f [] a ,我不确定如何表达相应的removed变体。也许像是

Codensity

更新:我尝试使用回溯improve monad创建这样的monad,它似乎以类似newtype LogicT r m a = LogicT { unLogicT :: forall r. (a -> m r -> m r) -> m r -> m r } 的方式定义:

MonadPlus

适用于回溯计算,即lowerLogic

然后我定义了{-# LANGUAGE RankNTypes, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, UndecidableInstances, DeriveFunctor #-} import Control.Monad import Control.Monad.Trans.Free import Control.Monad.Logic lowerLogic :: (MonadPlus m) => LogicT m a -> m a lowerLogic k = runLogicT k (\x k -> mplus (return x) k) mzero ,类似于后面的LogicT

MonadFree

然后,在补充相应的instance (Functor f, MonadFree f m) => MonadFree f (LogicT m) where wrap t = LogicT (\h z -> wrap (fmap (\p -> runLogicT p h z) t)) 实例

之后
improvePlus :: (Functor f, MonadPlus mr)
            => (forall m. (MonadFree f m, MonadPlus m) => m a)
            -> FreeT f mr a
improvePlus k = lowerLogic k

可以定义

k

然而,有些事情是不对的,因为从我最初的实验中可以看出,improvePlus kLogicT不同。我不确定,如果这是lowerLogic的基本限制,需要一个不同的,更复杂的monad,或者只是我错误地定义了"$date": "2015-08-27T13:50:49.000Z"(或其他东西)。

1 个答案:

答案 0 :(得分:10)

以下全部基于我对this very interesting paper posted by Matthew Pickering in his comment的误解:从幺半群到近半韵:MonadPlus的本质和 备选。所有结果都是他们的;所有的错误都是我的。

从免费幺半群到DList

为了建立直觉,首先考虑免费的幺半群[] Haskell类型Hask的类别。 []的一个问题是if 你有

(xs `mappend` ys) `mappend` zs = (xs ++ ys) ++ zs

然后评估需要遍历和重新遍历xs 每个左侧嵌套的mappend应用程序。

解决方案是以difference lists

的形式使用CPS
newtype DList a = DL { unDL :: [a] -> [a] }

本文考虑了这种的一般形式(称为Cayley 表示我们不依赖于自由幺半群:

newtype Cayley m = Cayley{ unCayley :: Endo m }

转化

toCayley :: (Monoid m) => m -> Cayley m
toCayley m = Cayley $ Endo $ \m' -> m `mappend` m'

fromCayley :: (Monoid m) => Cayley m -> m
fromCayley (Cayley k) = appEndo k mempty

两个概括方向

我们可以用两种方式概括上述结构:第一,by 考虑不超过Hask的幺半群,而是Hask的endofunctors; i.e. 单子;第二,通过丰富代数结构 近半环。

Free monad到Codensity

对于任何Haskell(endo)仿函数f,我们可以构造free monad Free f, 左嵌套绑定会产生类似的性能问题, 使用Cayley表示的类似解决方案 Codensity

近半环而不仅仅是幺半群

这是本文停止审查众所周知的概念的地方 由工作的Haskell程序员,并开始寻找其目标。一个 近半环就像一个戒指,除了更简单,因为它们都是和 乘法只需要幺半群。之间的联系 这两项操作是你所期望的:

zero |*| a = zero
(a |+| b) |*| c = (a |*| c) |+| (b |*| c)

其中(zero, |+|)(one, |*|)是两个幺半群 共享基地:

class NearSemiring a where
    zero :: a
    (|+|) :: a -> a -> a
    one :: a
    (|*|) :: a -> a -> a

免费近半环(超过Hask)原来如下 Forest类型:

newtype Forest a = Forest [Tree a]
data Tree a = Leaf | Node a (Forest a)

instance NearSemiring (Forest a) where
    zero = Forest []
    one = Forest [Leaf]
    (Forest xs) |+| (Forest ys) = Forest (xs ++ ys)
    (Forest xs) |*| (Forest ys) = Forest (concatMap g xs)
      where
        g Leaf = ys
        g (Node a n) = [Node a (n |*| (Forest ys))]

(好事我们没有交换性或倒置, those make free representations far from trivial ...)

然后,本文将Cayley表示法应用于两次 幺半群结构。

  

但是,如果我们天真地这样做,我们就会这样做   没有得到一个好的代表:我们想代表一个近乎半沉的,   因此必须考虑整个近半环的结构   帐户而不仅仅是一个选择的幺半群结构。 [...] [我们获得   在内同胚DC(N)上的内同胚的半环:

newtype DC n = DC{ unDC :: Endo (Endo n) }

instance (Monoid n) => NearSemiring (DC n) where
    f |*| g = DC $ unDC f `mappend` unDC g
    one = DC mempty
    f |+| g = DC $ Endo $ \h -> appEndo (unDC f) h `mappend` h
    zero = DC $ Endo $ const mempty

(我已经将这里的实施从文件略微改为 强调我们正在使用Endo结构两次)。我们什么时候 概括一下,这两层不会相同。然后是论文 继续说:

  

请注意,rep不是从NDC(N)的近乎半同态的同态   因为它不保留单位[...]尽管如此,[...]   如果,将保留近半环的计算语义   我们将值提升到表示,进行近乎半成品的计算   在那里,然后回到原来的近乎半环境。

MonadPlus几乎是近乎半枯的

然后,论文继续重新制定MonadPlus类型类 它对应于近乎半环的规则:(mzero, mplus)是幺半群:

m `mplus` mzero = m
mzero `mplus` m = m
m1 `mplus` (m2 `mplus` m3) = (m1 `mplus` m2) `mplus` m3

并按照预期与monad-monoid进行交互:

join mzero = mzero
join (m1 `mplus` m2) = join m1 `mplus` join m2

或者,使用绑定:

mzero >>= _ = mzero
(m1 `mplus` m2) >>= k = (m1 >>= k) `mplus` (m2 >>= k)

然而,这些 <{3}}的规则, 列为:

mzero >>= _  =  mzero
_ >> mzero   =  mzero

本文调用满足MonadPlus个实例 近乎半决定的法律&#34; nondeterminism monads&#34;,和 引用Maybe作为MonadPlus而非a m1 = Just Nothing的示例 nondeterminism monad,因为设置m2 = Just (Just False)join (m1 `mplus` m2) = join m1 `mplus` join m2Forest的反例。

Freedeterminism monads的Free和Cayley表示

把所有东西放在一起,一方面我们就像newtype FreeP f x = FreeP { unFreeP :: [FFreeP f x] } data FFreeP f x = PureP x | ConP (f (FreeP f x)) instance (Functor f) => Functor (FreeP f) where fmap f x = x >>= return . f instance (Functor f) => Monad (FreeP f) where return x = FreeP $ return $ PureP x (FreeP xs) >>= f = FreeP (xs >>= g) where g (PureP x) = unFreeP (f x) g (ConP x) = return $ ConP (fmap (>>= f) x) instance (Functor f) => MonadPlus (FreeP f) where mzero = FreeP mzero FreeP xs `mplus` FreeP ys = FreeP (xs `mplus` ys) 一样 免费的非确定性monad:

newtype (:^=>) f g x = Ran{ unRan :: forall y. (x -> f y) -> g y }
newtype (:*=>) f g x = Exp{ unExp :: forall y. (x -> y) -> (f y -> g y) }

instance Functor (g :^=> h) where
    fmap f m = Ran $ \k -> unRan m (k . f)

instance Functor (f :*=> g) where
    fmap f m = Exp $ \k -> unExp m (k . f)

newtype DCM f x = DCM {unDCM :: ((f :*=> f) :^=> (f :*=> f)) x}

instance Monad (DCM f) where
    return x = DCM $ Ran ($x)
    DCM (Ran m) >>= f = DCM $ Ran $ \g -> m $ \a -> unRan (unDCM (f a)) g

instance MonadPlus (DCM f) where
    mzero = DCM $ Ran $ \k -> Exp (const id)
    mplus m n = DCM $ Ran $ \sk -> Exp $ \f fk -> unExp (a sk) f (unExp (b sk) f fk)
      where
        DCM (Ran a) = m
        DCM (Ran b) = n

caylize :: (Monad m) => m a -> DCM m a
caylize x = DCM $ Ran $ \g -> Exp $ \h m -> x >>= \a -> unExp (g a) h m

-- I wish I called it DMC earlier...
runDCM :: (MonadPlus m) => DCM m a -> m a
runDCM m = unExp (f $ \x -> Exp $ \h m -> return (h x) `mplus` m) id mzero
  where
    DCM (Ran f) = m

另一方面,两个幺半群的双Cayley表示 层:

FreeP

本文给出了以下在a中运行的计算示例 对于anyOf :: (MonadPlus m) => [a] -> m a anyOf [] = mzero anyOf (x:xs) = anyOf xs `mplus` return x 表现不佳的非确定性monad:

length $ unFreeP (anyOf [1..100000] :: FreeP Identity Int)

确实,而

length $ unFreeP (runDCM $ anyOf [1..100000] :: FreeP Identity Int)

需要年龄,Cayley转型版

{{1}}

立即返回。