-
Notifications
You must be signed in to change notification settings - Fork 141
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
Add MonadFix instance for boxed vectors #312
Changes from 2 commits
915a5bb
f841564
746d714
4f01752
c7bb6d2
0b43390
9a27eb6
da92174
6dd926c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -176,11 +176,12 @@ import Control.DeepSeq ( NFData(rnf) | |
) | ||
|
||
import Control.Monad ( MonadPlus(..), liftM, ap ) | ||
import Control.Monad.ST ( ST ) | ||
import Control.Monad.ST ( ST, runST ) | ||
import Control.Monad.Primitive | ||
import qualified Control.Monad.Fail as Fail | ||
|
||
import Control.Monad.Fix ( MonadFix (mfix) ) | ||
import Control.Monad.Zip | ||
import Data.Function ( fix ) | ||
|
||
import Prelude hiding ( length, null, | ||
replicate, (++), concat, | ||
|
@@ -381,6 +382,24 @@ instance MonadZip Vector where | |
{-# INLINE munzip #-} | ||
munzip = unzip | ||
|
||
instance MonadFix Vector where | ||
-- We take care to dispose of v0 as soon as possible. | ||
-- We also avoid setting up the result vector to refer to | ||
-- itself. These measures should prevent memory leaks. | ||
-- It's perfectly safe to use non-monadic indexing within | ||
-- each element, as the result of indexing will be demanded | ||
-- as soon as the vector is produced. | ||
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. What I mean about this is that the use of 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. Thanks! I'll integrate that explanation into comment tomorrow. Right now it's somewhat cryptic |
||
{-# INLINE mfix #-} | ||
mfix f | ||
| null v0 = empty | ||
| otherwise = runST $ do | ||
h <- headM v0 | ||
return $ cons h $ | ||
generate (lv0 - 1) $ | ||
\i -> fix (\a -> f a ! (i + 1)) | ||
where | ||
v0 = fix (f . head) | ||
!lv0 = length v0 | ||
|
||
instance Applicative.Applicative Vector where | ||
{-# INLINE pure #-} | ||
|
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 no longer know what I meant by "We also avoid setting up the result vector to refer to itself." Perhaps We should just change the above to
-- To prevent memory leaks, we take care to dispose of v0 as soon as possible (see headM docs).
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.
Makes sense. I don't understand what does it mean either