Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 145
Export unstreamPrimM & unsafeUnstreamPrimM#544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base:master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -164,7 +164,7 @@ module Data.Vector.Generic ( | ||
| -- * Fusion support | ||
| -- ** Conversion to/from Bundles | ||
| stream, unstream, unstreamM, streamR, unstreamR, | ||
| stream, unstream, unstreamM, unstreamPrimM, unsafeUnstreamPrimM, streamR, unstreamR, | ||
| -- ** Recycling support | ||
| new, clone, | ||
| @@ -2621,23 +2621,51 @@ unstreamM s = do | ||
| xs <- MBundle.toList s | ||
| return $ unstream $ Bundle.unsafeFromList (MBundle.size s) xs | ||
| -- | Load a monadic stream bundle into a newly allocated vector. It | ||
| -- makes writes to a single buffer and copies it when finished. Note | ||
| -- for monads that encode nondeterminism result may be different | ||
| -- from `unstreamM`. | ||
| -- | ||
| -- @since NEXT_VERSION | ||
| unstreamPrimM :: (PrimMonad m, Vector v a) => MBundle m u a -> m (v a) | ||
| {-# INLINE_FUSED unstreamPrimM #-} | ||
| unstreamPrimM s = M.munstream s >>= unsafeFreeze | ||
| unstreamPrimM s = M.munstream s >>= freeze | ||
| -- | Load a monadic stream bundle into a newly allocated vector. This | ||
| -- function create mutable buffer, writes to it and then | ||
| -- 'unsafeFreeze's it. | ||
| -- | ||
| -- This function is unsafe. For monads that encode nondeterminism | ||
| -- (e.g. @ListT@) it allows to break referential transparency. More | ||
| -- precisely if 'unsafeFreeze' is called more than once we will | ||
| -- perform writes into buffer which is considered immutable. | ||
Comment on lines
+2639
to
+2642
| ||
| -- | ||
| -- In particular it's certainly unsafe to use this function when | ||
| -- type of monad is polymorphic but it's safe to use for monads such | ||
| -- as @IO@, @ST@, @Reader@, @Writer@, @State@. | ||
| -- | ||
| -- @since NEXT_VERSION | ||
| unsafeUnstreamPrimM :: (PrimMonad m, Vector v a) => MBundle m u a -> m (v a) | ||
| {-# INLINE_FUSED unsafeUnstreamPrimM #-} | ||
| unsafeUnstreamPrimM s = M.munstream s >>= unsafeFreeze | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned in my other comment I don't think there is anything unsafe about this function. I would love to be proven wrong with an example of using some known | ||
| -- 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_IO = unsafeUnstreamPrimM | ||
| unstreamPrimM_ST :: Vector v a => MBundle (ST s) u a -> ST s (v a) | ||
| {-# INLINE unstreamPrimM_ST #-} | ||
| unstreamPrimM_ST = unstreamPrimM | ||
| unstreamPrimM_ST = unsafeUnstreamPrimM | ||
| {-# RULES | ||
| "unstreamM[IO]" unstreamM = unstreamPrimM_IO | ||
| "unstreamM[ST]" unstreamM = unstreamPrimM_ST #-} | ||
| "unstreamM[IO]" unstreamM = unstreamPrimM_IO | ||
| "unstreamM[ST]" unstreamM = unstreamPrimM_ST | ||
| "unstreamPrimM[IO]" unstreamPrimM = unstreamPrimM_IO | ||
| "unstreamPrimM[ST]" unstreamPrimM = unstreamPrimM_ST | ||
| #-} | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible? Can the results be different? I mean, I believed that the results are always the same; I thought I just can't prove it mathematically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure myself. But they are different operationally:
unstreamMuses immutable data structures andunstreamPrimMand in principle can observe mutations.ListTmutates elements in particular order so results are always same.Perhaps some lawless variant of
OmegaTbuilt on top https://hackage-content.haskell.org/package/control-monad-omega-0.3.3/docs/Control-Monad-Omega.html will work. Or some tricks withContTThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't this is the case at all and IMHO
unstreamPrimMis absolutely safe withunsafeFreezeinstead offreezeat the end.If this operation is unsafe for some transformer that would mean its instance for
PrimMonadis incorrect.