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

dfe*_*uer 7 haskell

流包定义

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