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) -> rK
t
KV
KV
t