KV
Size: a a a
KV
K
Free m >>= f = Free ((>>= f) <$> m)- каждый раз, когда вызывается
>>=
оно обходит всё дерево, заменяя узлы Pure a
на f a
. Каждый раз, сверху вниз.Codensity m
и его байнд устроен так, что он идёт от листьев, и всё дерево не обходится.Free f
, то берётся Codensity (Free f)
и разгибается через improve
. И поскольку дерево было построено не через Free.>>=
а через Codensity.>>=
оно работает быстрее.KV
t
Free m >>= f = Free ((>>= f) <$> m)- каждый раз, когда вызывается
>>=
оно обходит всё дерево, заменяя узлы Pure a
на f a
. Каждый раз, сверху вниз.Codensity m
и его байнд устроен так, что он идёт от листьев, и всё дерево не обходится.Free f
, то берётся Codensity (Free f)
и разгибается через improve
. И поскольку дерево было построено не через Free.>>=
а через Codensity.>>=
оно работает быстрее.K
Codensit
-ями, но я сам пытался въехать в то как они работают, но понял только зачем их применяют и как. Чёрная магия.K
instance Applicative f => Monad (Free f) where
return = pure
{-# INLINE return #-}
Pure a >>= f = f a
Free m >>= f = Free ((>>= f) <$> m)
t
instance Applicative f => Monad (Free f) where
return = pure
{-# INLINE return #-}
Pure a >>= f = f a
Free m >>= f = Free ((>>= f) <$> m)
Codensity
"t
KV
t
t
Free m >>= f = Free ((>>= f) <$> m)- каждый раз, когда вызывается
>>=
оно обходит всё дерево, заменяя узлы Pure a
на f a
. Каждый раз, сверху вниз.Codensity m
и его байнд устроен так, что он идёт от листьев, и всё дерево не обходится.Free f
, то берётся Codensity (Free f)
и разгибается через improve
. И поскольку дерево было построено не через Free.>>=
а через Codensity.>>=
оно работает быстрее.K
newtype Codensity m a = Codensity
{ runCodensity :: forall b. (a -> m b) -> m b
}
>>=
, частично применённый к m a
.type Cont r a = (a -> r) -> r
K
t
KV
KV
t