- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最近有一个question关于DList
之间的关系<-> []
与 Codensity
相比<-> Free
.
这让我想到MonadPlus
有没有这种东西. Codensity
monad 仅对 monadic 操作提高渐近性能,而不是 mplus
.
此外,虽然曾经有 Control.MonadPlus.Free
, 一直是 removed赞成FreeT f []
.而且由于没有明确的免费MonadPlus
,我不确定如何表达相应的 improve
变体。也许像
improvePlus :: Functor f => (forall m. (MonadFree f m, MonadPlus m) => m a) -> FreeT f [] a
LogicT
创建这样的 monad monad,似乎以类似于
Codensity
的方式定义:
newtype LogicT r m a = LogicT { unLogicT :: forall r. (a -> m r -> m r) -> m r -> m r }
MonadPlus
.
lowerLogic
, 类似于
lowerCodensity
如下:
{-# 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
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 k
.我不确定,这是否是
LogicT
的基本限制并且需要一个不同的、更复杂的 monad,或者如果我定义了
lowerLogic
(或其他)错误。
最佳答案
以下都是基于我对此的(错误)理解
Matthew Pickering 在他的
评论:From monoids to near-semirings: the essence of MonadPlus andAlternative (E. Rivas, M. Jaskelioff, T. Schrijvers) .所有的结果都是他们的;所有的错误都是我的。
从自由幺半群到 DList
为了建立直觉,首先考虑自由幺半群[]
超过
Haskell 类型的类别 Hask
. []
的一个问题是如果
你有
(xs `mappend` ys) `mappend` zs = (xs ++ ys) ++ zs
xs
为了
mappend
的每个左嵌套应用程序.
newtype DList a = DL { unDL :: [a] -> [a] }
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
Hask
, 但超过
Hask
的内仿函数;
Free
单子(monad)到
Codensity
f
,我们可以构造
freemonad
Free f
, 和
Codensity
.
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))]
However, if we do this naively, we do not get a good representation: we want to represent a near-semiring, and therefore the whole near-semiring structure must be taken into account and not just one chosen monoid structure. [...] [W]e obtain the semiring of endomorphisms over endomorphisms
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
结构两次)。我们什么时候
Note that
rep
is not a near-semiring homomorphism fromN
intoDC(N)
as it does not preserve the unit [...] Nevertheless, [...] the semantics of a computation over a near-semiring will be preserved if we lift values to the representation, do the near-semiring computation there, and then go back to the original near-semiring.
MonadPlus
几乎是半成品
MonadPlus
类型类所以
(mzero, mplus)
是幺半群:
m `mplus` mzero = m
mzero `mplus` m = m
m1 `mplus` (m2 `mplus` m3) = (m1 `mplus` m2) `mplus` m3
join mzero = mzero
join (m1 `mplus` m2) = join m1 `mplus` join m2
mzero >>= _ = mzero
(m1 `mplus` m2) >>= k = (m1 >>= k) `mplus` (m2 >>= k)
MonadPlus
typeclass from base
的规则,
mzero >>= _ = mzero
_ >> mzero = mzero
MonadPlus
满足的实例
Maybe
以
MonadPlus
为例但不是一个
m1 = Just Nothing
和
m2 = Just
(Just False)
是
join (m1 `mplus` m2) = join m1
`mplus` join m2
的反例.
Forest
-喜欢
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)
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
FreeP
表现不佳的非确定性 monad :
anyOf :: (MonadPlus m) => [a] -> m a
anyOf [] = mzero
anyOf (x:xs) = anyOf xs `mplus` return x
length $ unFreeP (anyOf [1..100000] :: FreeP Identity Int)
length $ unFreeP (runDCM $ anyOf [1..100000] :: FreeP Identity Int)
关于haskell - 是否存在渐近优化一系列 MonadPlus 操作的 Codensity MonadPlus?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32252312/
谁能证实这个算法的复杂度是 O(n^2)? a = 0 b = 0 c = n while (b <= c) { for (j = b; j<=c; j++) { a
问题(数据结构): 我们应该使用哪种表示来计算 O(|V|+|E|) 中图顶点的入度?这应该如何在 Khan 的算法中保持而不损害运行时间(渐近地)?证明您的主张。 我的尝试:我们应该使用矩阵表示来计
在某些情况下,对问题的蛮力方法具有复杂性,在性能方面不够好。 让我们举个例子西塔(n^2)。 使用递归方法可以将其改进为 Theta(nlogn)。 显然,渐近地人们会选择使用递归方法,因为对于越来越
我在 C++11 中使用 std::unordered_map。我在字符串键和复合数据类型之间做出决定(比如将两个 long 放在一个结构中以保存 UUID)。 当 hashmap 使用 std::s
它是 f(n)=theta(h(n)) 因为 theta 是可传递的。但是谁能解释为什么 h(n)=theta(f(n))。 最佳答案 通过定义扩展 Big-O 符号通常会使事情变得简单。 关于alg
我是一名优秀的程序员,十分优秀!