unstreamM fusion incredibly easy to break
- Dominant language
- Haskell
- Stars
- 400
- Forks
- 145
- PR merge metrics
- No merged PRs in 30d
Description
It turns out that `Data.Vector.Generic.unstreamM` will more-often-than-not fail to fuse. For evidence look no farther than the implementation:
```haskell
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.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.