Created
February 8, 2019 23:35
-
-
Save chessai/47f559618201b4cac61b0f930ea8b338 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# language BangPatterns #-} | |
{-# language ScopedTypeVariables #-} | |
{-# language UnboxedTuples #-} | |
module Array (mapMaybe) where | |
import Control.Monad.ST | |
import Data.Primitive.Array | |
data Alls = AllNothing | NotAllNothing | |
emptyMutableArray :: ST s (MutableArray s a) | |
emptyMutableArray = newArray 0 (error "impossible") | |
{-# noinline emptyMutableArray #-} | |
mapMaybe :: forall a b. (a -> Maybe b) -> Array a -> Array b | |
mapMaybe p arr = runST $ do | |
let !sz = sizeofArray arr | |
let go2 :: MutableArray s b -> Int -> Int -> ST s (Int, MutableArray s b) | |
go2 marr !ixSrc !ixDst = if ixSrc < sz | |
then do | |
a <- indexArrayM arr ixSrc | |
case p a of | |
Just b -> do | |
writeArray marr ixDst b | |
go2 marr (ixSrc + 1) (ixDst + 1) | |
Nothing -> go2 marr (ixSrc + 1) ixDst | |
else pure (ixDst, marr) | |
let go :: Int -> Int -> Bool -> ST s (Int, MutableArray s b) | |
go !ixSrc !ixDst !encountered = if ixSrc < sz | |
then do | |
a <- indexArrayM arr ixSrc | |
case p a of | |
Just b -> do | |
marr <- newArray (sz - ixSrc) b | |
go2 marr (ixSrc + 1) (ixDst + 1) | |
Nothing -> go (ixSrc + 1) ixDst False | |
else do | |
marrEmpty <- emptyMutableArray | |
return (ixDst, marrEmpty) | |
(dstLen, marr) <- go 0 0 False | |
empty <- emptyMutableArray | |
if marr == empty | |
then unsafeFreezeArray marr | |
-- we need resizing primitives? | |
else unsafeFreezeArray marr | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment