我可以用严格的数据类型打结吗?

时间:2017-08-26 23:11:11

标签: haskell

流媒体包定义

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构造函数。然后确保一切都是强制性的,并将它变成更严格的类型。

0 个答案:

没有答案