流媒体包定义
data Stream f m r = Step !(f (Stream f m r))
| Effect (m (Stream f m r))
| Return r
empty
的{{1}}实现已定义
never
对于基本上纯粹的东西而言,这一切都是非常单一的,这是图书馆出于性能原因通常试图避免的。显而易见的纯粹版本将是
never :: (Monad m, Applicative f)
=> Stream f m r
never = let loop = Effect (return (Step (pure loop))) in loop
不幸的是,由于never = let loop = Step (pure loop) in loop
是严格的,因此对于具有严格Step
的仿函数,例如pure
,这将会爆发。有没有办法解决?我唯一的想法是荒谬的不安全,而且我不知道它是否会出现可怕的错误。
Identity
我的想法是构建类似data StreamL f m r = StepL (f (StreamL f m r))
| EffectL (m (StreamL f m r))
| ReturnL r
never :: forall f m r. Applicative f => Stream f m r
never = case loop of
StepL x -> x `pseq` unsafeCoerce loop
where
loop :: StreamL f m r
loop = StepL (pure loop)
{-# NOINLINE loop #-}
{-# NOINLINE never #-}
的内容,但使用惰性never
构造函数。然后确保一切都是强制性的,并将它变成更严格的类型。