流包定义
data Stream f m r = Step !(f (Stream f m r))
| Effect (m (Stream f m r))
| Return r
Run Code Online (Sandbox Code Playgroud)
它的实施empty,被称为never,被定义
never :: (Monad m, Applicative f)
=> Stream f m r
never = let loop = Effect (return (Step (pure loop))) in loop
Run Code Online (Sandbox Code Playgroud)
对于基本上纯粹的东西来说,这都是非常单一的,这是图书馆通常为了性能原因而试图避免的.显而易见的纯粹版本将是
never = let loop = Step (pure loop) in loop
Run Code Online (Sandbox Code Playgroud)
不幸的是,既然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 #-}
Run Code Online (Sandbox Code Playgroud)
我的想法是构建一些类似的东西never,但是使用一个懒惰的StepL构造函数.然后确保一切都是强制的,并将它变成更严格的类型.
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |