It turns out that Data.Vector.Generic.unstreamM will more-often-than-not fail to fuse. For evidence look no farther than the implementation:
unstreamM :: (Monad m, Vector v a) => MBundle m u a -> m (v a)
{-# INLINE_FUSED unstreamM #-}
unstreamM s = do
xs <- MBundle.toList s
return $ unstream $ Bundle.unsafeFromList (MBundle.size s) xs
unstreamPrimM :: (PrimMonad m, Vector v a) => MBundle m u a -> m (v a)
{-# INLINE_FUSED unstreamPrimM #-}
unstreamPrimM s = M.munstream s >>= unsafeFreeze
-- FIXME: the next two functions are only necessary for the specialisations
unstreamPrimM_IO :: Vector v a => MBundle IO u a -> IO (v a)
{-# INLINE unstreamPrimM_IO #-}
unstreamPrimM_IO = unstreamPrimM
unstreamPrimM_ST :: Vector v a => MBundle (ST s) u a -> ST s (v a)
{-# INLINE unstreamPrimM_ST #-}
unstreamPrimM_ST = unstreamPrimM
{-# RULES
"unstreamM[IO]" unstreamM = unstreamPrimM_IO
"unstreamM[ST]" unstreamM = unstreamPrimM_ST #-}
Note how unstreamM bundle will materialise the stream contents as a list in all monads except IO and ST. This seems Very Bad, although I'm not sure what can really be done. In principle we could use unstreamPrimM for any PrimMonad, but this of course we can't know during simplification.
It turns out that
Data.Vector.Generic.unstreamMwill more-often-than-not fail to fuse. For evidence look no farther than the implementation:Note how
unstreamM bundlewill materialise the stream contents as a list in all monads exceptIOandST. This seems Very Bad, although I'm not sure what can really be done. In principle we could useunstreamPrimMfor anyPrimMonad, but this of course we can't know during simplification.