├── cabal.project ├── .ghci ├── Setup.lhs ├── cabal.haskell-ci ├── .gitignore ├── README.markdown ├── CHANGELOG.markdown ├── .vim.custom ├── LICENSE ├── hybrid-vectors.cabal ├── src └── Data │ └── Vector │ ├── Hybrid │ ├── Internal.hs │ └── Mutable.hs │ ├── Mixed │ ├── Internal.hs │ └── Mutable.hs │ ├── Hybrid.hs │ └── Mixed.hs └── .github └── workflows └── haskell-ci.yml /cabal.project: -------------------------------------------------------------------------------- 1 | packages: . 2 | -------------------------------------------------------------------------------- /.ghci: -------------------------------------------------------------------------------- 1 | :set -isrc -idist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h 2 | -------------------------------------------------------------------------------- /Setup.lhs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/runhaskell 2 | > module Main (main) where 3 | 4 | > import Distribution.Simple 5 | 6 | > main :: IO () 7 | > main = defaultMain 8 | -------------------------------------------------------------------------------- /cabal.haskell-ci: -------------------------------------------------------------------------------- 1 | no-tests-no-benchmarks: False 2 | unconstrained: False 3 | -- irc-channels: irc.freenode.org#haskell-lens 4 | irc-if-in-origin-repo: True 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-newstyle 3 | docs 4 | wiki 5 | TAGS 6 | tags 7 | wip 8 | .DS_Store 9 | .*.swp 10 | .*.swo 11 | *.o 12 | *.hi 13 | *~ 14 | *# 15 | .stack-work/ 16 | cabal-dev 17 | *.chi 18 | *.chs.h 19 | *.dyn_o 20 | *.dyn_hi 21 | .hpc 22 | .hsenv 23 | .cabal-sandbox/ 24 | cabal.sandbox.config 25 | *.prof 26 | *.aux 27 | *.hp 28 | *.eventlog 29 | cabal.project.local 30 | cabal.project.local~ 31 | .HTF/ 32 | .ghc.environment.* 33 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | hybrid-vectors 2 | ============== 3 | 4 | [![Hackage](https://img.shields.io/hackage/v/hybrid-vectors.svg)](https://hackage.haskell.org/package/hybrid-vectors) [![Build Status](https://github.com/ekmett/hybrid-vectors/workflows/Haskell-CI/badge.svg)](https://github.com/ekmett/hybrid-vectors/actions?query=workflow%3AHaskell-CI) 5 | 6 | Hybrid vectors e.g. mixed unboxed/boxed vectors. 7 | 8 | This can be used to run algorithms such as those from `vector-algorithms` over a mixture of boxed and unboxed data. 9 | 10 | Contact Information 11 | ------------------- 12 | 13 | Contributions and bug reports are welcome! 14 | 15 | Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net. 16 | 17 | -Edward Kmett 18 | -------------------------------------------------------------------------------- /CHANGELOG.markdown: -------------------------------------------------------------------------------- 1 | 0.2.5 [2024.12.04] 2 | ------------------ 3 | * Drop support for pre-8.0 versions of GHC. 4 | 5 | 0.2.4 [2023.08.06] 6 | ------------------ 7 | * Future-proof against `foldl'` being added to the `Prelude`. 8 | 9 | 0.2.3 [2020.06.21] 10 | ------------------ 11 | * Allow building with `vector-0.13.*`. 12 | 13 | 0.2.2 [2018.01.18] 14 | ------------------ 15 | * Add `Semigroup` instance for `Vector`. 16 | 17 | 0.2.1 18 | ----- 19 | * Support `vector` 0.11 20 | 21 | 0.2 22 | --- 23 | * Remove `Mixed`. A bug in GHC 7.10.1 prevents it from working. 24 | 25 | 0.1.2.1 26 | ------- 27 | * Support `deepseq` 1.5 28 | 29 | 0.1.2 30 | ----- 31 | * GHC 7.8.1rc2 compatibility 32 | 33 | 0.1 34 | --- 35 | * Repository initialized. 36 | * Hybrid and Mixed vectors added. 37 | -------------------------------------------------------------------------------- /.vim.custom: -------------------------------------------------------------------------------- 1 | " Add the following to your .vimrc to automatically load this on startup 2 | 3 | " if filereadable(".vim.custom") 4 | " so .vim.custom 5 | " endif 6 | 7 | function StripTrailingWhitespace() 8 | let myline=line(".") 9 | let mycolumn = col(".") 10 | silent %s/ *$// 11 | call cursor(myline, mycolumn) 12 | endfunction 13 | 14 | " enable syntax highlighting 15 | syntax on 16 | 17 | " search for the tags file anywhere between here and / 18 | set tags=TAGS;/ 19 | 20 | " highlight tabs and trailing spaces 21 | set listchars=tab:‗‗,trail:‗ 22 | set list 23 | 24 | " f2 runs hasktags 25 | map :exec ":!hasktags -x -c --ignore src" 26 | 27 | " strip trailing whitespace before saving 28 | " au BufWritePre *.hs,*.markdown silent! cal StripTrailingWhitespace() 29 | 30 | " rebuild hasktags after saving 31 | au BufWritePost *.hs silent! :exec ":!hasktags -x -c --ignore src" 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013 Edward Kmett 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR 20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /hybrid-vectors.cabal: -------------------------------------------------------------------------------- 1 | name: hybrid-vectors 2 | category: Data, Vector 3 | version: 0.2.5 4 | license: BSD3 5 | cabal-version: >= 1.10 6 | license-file: LICENSE 7 | author: Edward A. Kmett 8 | maintainer: Edward A. Kmett 9 | stability: experimental 10 | homepage: http://github.com/ekmett/hybrid-vectors 11 | bug-reports: http://github.com/ekmett/hybrid-vectors/issues 12 | copyright: Copyright (C) 2013 Edward A. Kmett 13 | build-type: Simple 14 | synopsis: Hybrid vectors e.g. Mixed Boxed/Unboxed vectors 15 | extra-source-files: 16 | .ghci 17 | .gitignore 18 | .vim.custom 19 | description: Hybrid vectors e.g. Mixed Boxed/Unboxed vectors. 20 | tested-with: GHC == 8.0.2 21 | , GHC == 8.2.2 22 | , GHC == 8.4.4 23 | , GHC == 8.6.5 24 | , GHC == 8.8.4 25 | , GHC == 8.10.7 26 | , GHC == 9.0.2 27 | , GHC == 9.2.8 28 | , GHC == 9.4.8 29 | , GHC == 9.6.6 30 | , GHC == 9.8.4 31 | , GHC == 9.10.1 32 | , GHC == 9.12.1 33 | 34 | source-repository head 35 | type: git 36 | location: https://github.com/ekmett/hybrid-vectors.git 37 | 38 | library 39 | build-depends: 40 | base >= 4.9 && < 5, 41 | primitive >= 0.5 && < 0.10, 42 | vector >= 0.11 && < 0.14 43 | 44 | hs-source-dirs: src 45 | 46 | exposed-modules: 47 | Data.Vector.Hybrid 48 | Data.Vector.Hybrid.Internal 49 | Data.Vector.Hybrid.Mutable 50 | 51 | ghc-options: -Wall -O2 52 | default-language: Haskell2010 53 | 54 | if impl(ghc >= 8.6) 55 | ghc-options: -Wno-star-is-type 56 | -------------------------------------------------------------------------------- /src/Data/Vector/Hybrid/Internal.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP, FlexibleInstances, GADTs #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving, KindSignatures #-} 3 | {-# LANGUAGE MultiParamTypeClasses, ScopedTypeVariables, TypeFamilies #-} 4 | {-# LANGUAGE TypeOperators #-} 5 | {-# LANGUAGE UndecidableInstances #-} 6 | 7 | module Data.Vector.Hybrid.Internal 8 | ( MVector(..) 9 | , Vector(..) 10 | ) where 11 | 12 | import Control.Monad 13 | import qualified Data.Foldable as F 14 | import Data.Monoid 15 | import Data.Semigroup 16 | import Data.Vector.Fusion.Bundle as Stream 17 | import qualified Data.Vector.Generic as G 18 | import qualified Data.Vector.Generic.Mutable as GM 19 | 20 | import Data.Data 21 | import Prelude hiding (drop, init, length, map, null, read, replicate, 22 | reverse, tail, take) 23 | import Text.Read 24 | 25 | data MVector :: (* -> * -> *) -> (* -> * -> *) -> * -> * -> * where 26 | MV :: !(u s a) -> !(v s b) -> MVector u v s (a, b) 27 | 28 | instance (GM.MVector u a, GM.MVector v b) => GM.MVector (MVector u v) (a, b) where 29 | basicLength (MV ks _) = GM.basicLength ks 30 | {-# INLINE basicLength #-} 31 | basicUnsafeSlice s e (MV ks vs) = MV (GM.basicUnsafeSlice s e ks) (GM.basicUnsafeSlice s e vs) 32 | {-# INLINE basicUnsafeSlice #-} 33 | basicOverlaps (MV ks vs) (MV ks' vs') = GM.basicOverlaps ks ks' || GM.basicOverlaps vs vs' 34 | {-# INLINE basicOverlaps #-} 35 | basicUnsafeNew n = liftM2 MV (GM.basicUnsafeNew n) (GM.basicUnsafeNew n) 36 | {-# INLINE basicUnsafeNew #-} 37 | basicUnsafeReplicate n (k,v) = liftM2 MV (GM.basicUnsafeReplicate n k) (GM.basicUnsafeReplicate n v) 38 | {-# INLINE basicUnsafeReplicate #-} 39 | basicUnsafeRead (MV ks vs) n = liftM2 (,) (GM.basicUnsafeRead ks n) (GM.basicUnsafeRead vs n) 40 | {-# INLINE basicUnsafeRead #-} 41 | basicUnsafeWrite (MV ks vs) n (k,v) = do 42 | GM.basicUnsafeWrite ks n k 43 | GM.basicUnsafeWrite vs n v 44 | {-# INLINE basicUnsafeWrite #-} 45 | basicClear (MV ks vs) = do 46 | GM.basicClear ks 47 | GM.basicClear vs 48 | {-# INLINE basicClear #-} 49 | basicSet (MV ks vs) (k,v) = do 50 | GM.basicSet ks k 51 | GM.basicSet vs v 52 | {-# INLINE basicSet #-} 53 | basicUnsafeCopy (MV ks vs) (MV ks' vs') = do 54 | GM.basicUnsafeCopy ks ks' 55 | GM.basicUnsafeCopy vs vs' 56 | {-# INLINE basicUnsafeCopy #-} 57 | basicUnsafeMove (MV ks vs) (MV ks' vs') = do 58 | GM.basicUnsafeMove ks ks' 59 | GM.basicUnsafeMove vs vs' 60 | {-# INLINE basicUnsafeMove #-} 61 | basicUnsafeGrow (MV ks vs) n = liftM2 MV (GM.basicUnsafeGrow ks n) (GM.basicUnsafeGrow vs n) 62 | {-# INLINE basicUnsafeGrow #-} 63 | basicInitialize (MV ks vs) = GM.basicInitialize ks >> GM.basicInitialize vs 64 | {-# INLINE basicInitialize #-} 65 | 66 | -- hybrid vectors 67 | data Vector :: (* -> *) -> (* -> *) -> * -> * where 68 | V :: !(u a) -> !(v b) -> Vector u v (a, b) 69 | 70 | type instance G.Mutable (Vector u v) = MVector (G.Mutable u) (G.Mutable v) 71 | 72 | instance (G.Vector u a, G.Vector v b) => G.Vector (Vector u v) (a, b) where 73 | basicUnsafeFreeze (MV ks vs) = liftM2 V (G.basicUnsafeFreeze ks) (G.basicUnsafeFreeze vs) 74 | {-# INLINE basicUnsafeFreeze #-} 75 | basicUnsafeThaw (V ks vs) = liftM2 MV (G.basicUnsafeThaw ks) (G.basicUnsafeThaw vs) 76 | {-# INLINE basicUnsafeThaw #-} 77 | basicLength (V ks _) = G.basicLength ks 78 | {-# INLINE basicLength #-} 79 | basicUnsafeSlice i j (V ks vs) = V (G.basicUnsafeSlice i j ks) (G.basicUnsafeSlice i j vs) 80 | {-# INLINE basicUnsafeSlice #-} 81 | basicUnsafeIndexM (V ks vs) n = liftM2 (,) (G.basicUnsafeIndexM ks n) (G.basicUnsafeIndexM vs n) 82 | {-# INLINE basicUnsafeIndexM #-} 83 | basicUnsafeCopy (MV ks vs) (V ks' vs') = do 84 | G.basicUnsafeCopy ks ks' 85 | G.basicUnsafeCopy vs vs' 86 | {-# INLINE basicUnsafeCopy #-} 87 | elemseq (V ks vs) (k,v) b = G.elemseq ks k (G.elemseq vs v b) 88 | {-# INLINE elemseq #-} 89 | 90 | instance (G.Vector u a, G.Vector v b, c ~ (a, b)) => Semigroup (Vector u v c) where 91 | (<>) = (G.++) 92 | sconcat = mconcat . F.toList 93 | 94 | instance (G.Vector u a, G.Vector v b, c ~ (a, b)) => Monoid (Vector u v c) where 95 | #if !(MIN_VERSION_base(4,11,0)) 96 | mappend = (G.++) 97 | {-# INLINE mappend #-} 98 | #endif 99 | mempty = G.empty 100 | {-# INLINE mempty #-} 101 | mconcat = G.concat 102 | {-# INLINE mconcat #-} 103 | 104 | instance (G.Vector u a, G.Vector v b, Show a, Show b, c ~ (a, b)) => Show (Vector u v c) where 105 | showsPrec = G.showsPrec 106 | 107 | instance (G.Vector u a, G.Vector v b, Read a, Read b, c ~ (a, b)) => Read (Vector u v c) where 108 | readPrec = G.readPrec 109 | readListPrec = readListPrecDefault 110 | 111 | instance (Data a, Data b, Typeable u, Typeable v, G.Vector u a, G.Vector v b, c ~ (a, b)) => Data (Vector u v c) where 112 | gfoldl = G.gfoldl 113 | toConstr _ = error "toConstr" -- TODO: virtual constructor 114 | gunfold _ _ = error "gunfold" -- TODO: virtual constructor 115 | dataTypeOf _ = mkNoRepType "Data.Vector.Hybrid.Vector" 116 | dataCast1 = G.dataCast 117 | 118 | 119 | instance (G.Vector u a, G.Vector v b, Eq a, Eq b, c ~ (a, b)) => Eq (Vector u v c) where 120 | xs == ys = Stream.eq (G.stream xs) (G.stream ys) 121 | {-# INLINE (==) #-} 122 | 123 | xs /= ys = not (Stream.eq (G.stream xs) (G.stream ys)) 124 | {-# INLINE (/=) #-} 125 | 126 | 127 | -- See http://trac.haskell.org/vector/ticket/12 128 | instance (G.Vector u a, G.Vector v b, Ord a, Ord b, c ~ (a, b)) => Ord (Vector u v c) where 129 | {-# INLINE compare #-} 130 | compare xs ys = Stream.cmp (G.stream xs) (G.stream ys) 131 | 132 | {-# INLINE (<) #-} 133 | xs < ys = Stream.cmp (G.stream xs) (G.stream ys) == LT 134 | 135 | {-# INLINE (<=) #-} 136 | xs <= ys = Stream.cmp (G.stream xs) (G.stream ys) /= GT 137 | 138 | {-# INLINE (>) #-} 139 | xs > ys = Stream.cmp (G.stream xs) (G.stream ys) == GT 140 | 141 | {-# INLINE (>=) #-} 142 | xs >= ys = Stream.cmp (G.stream xs) (G.stream ys) /= LT 143 | 144 | -------------------------------------------------------------------------------- /src/Data/Vector/Mixed/Internal.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 3 | {-# LANGUAGE KindSignatures #-} 4 | {-# LANGUAGE GADTs #-} 5 | {-# LANGUAGE MultiParamTypeClasses #-} 6 | {-# LANGUAGE BangPatterns #-} 7 | {-# LANGUAGE UndecidableInstances #-} 8 | {-# LANGUAGE FlexibleInstances #-} 9 | {-# LANGUAGE TypeFamilies #-} 10 | {-# LANGUAGE ScopedTypeVariables #-} 11 | {-# LANGUAGE FlexibleContexts #-} 12 | {-# LANGUAGE FunctionalDependencies #-} 13 | 14 | -- {-# OPTIONS_GHC -fno-method-sharing #-} -- See: http://trac.haskell.org/vector/ticket/12 15 | 16 | module Data.Vector.Mixed.Internal 17 | ( MVector(..), mboxed, munboxed 18 | , Vector(..), boxed, unboxed 19 | , Mixed(..) 20 | ) where 21 | 22 | import Control.Applicative 23 | import Control.Monad 24 | import Data.Monoid 25 | import Data.Foldable 26 | import Data.Traversable 27 | import qualified Data.Vector.Generic.Mutable as GM 28 | import qualified Data.Vector.Generic as G 29 | import qualified Data.Vector as B 30 | import qualified Data.Vector.Mutable as BM 31 | import qualified Data.Vector.Storable as S 32 | import qualified Data.Vector.Primitive as P 33 | import qualified Data.Vector.Unboxed as U 34 | import qualified Data.Vector.Hybrid as H 35 | import Data.Vector.Fusion.Stream as Stream 36 | import Data.Data 37 | import Prelude hiding ( length, null, replicate, reverse, map, read, take, drop, init, tail ) 38 | import Text.Read 39 | 40 | -- | Vector doesn't provide a way to recover the type of the immutable vector from the mutable vector type 41 | -- 42 | -- This would otherwise prevent us from finishing the implementation of 'basicUnsafeFreeze' in 'Vector' 43 | -- 44 | -- This class captures the invariants necessary to 'hide' the choice of vector type from the user in such 45 | -- a way that we can go from mutable vector to immutabl vector and back again. 46 | class 47 | ( Typeable mv 48 | , Typeable v 49 | , mv ~ G.Mutable v 50 | , GM.MVector mv a 51 | , G.Vector v a 52 | ) => Mixed mv v a | mv -> v, v -> mv where 53 | 54 | mmix :: mv s a -> MVector s a 55 | mmix = MV 56 | 57 | mix :: v a -> Vector a 58 | mix = V 59 | 60 | instance Mixed B.MVector B.Vector a 61 | instance S.Storable a => Mixed S.MVector S.Vector a 62 | instance P.Prim a => Mixed P.MVector P.Vector a 63 | instance U.Unbox a => Mixed U.MVector U.Vector a 64 | instance (Mixed u v a, Mixed u' v' b) => Mixed (H.MVector u u') (H.Vector v v') (a, b) 65 | instance Mixed MVector Vector a where 66 | mmix = id -- don't nest! 67 | mix = id 68 | 69 | -- | A @MVector s a@ is mutable vector that could have any vector type underneath 70 | data MVector :: * -> * -> * where 71 | MV :: Mixed mv v a => !(mv s a) -> MVector s a 72 | 73 | {-# RULES 74 | "mstream/MV" forall v. 75 | GM.mstream (MV v) = GM.mstream v 76 | 77 | "mstreamR/MV" forall v. 78 | GM.mstreamR (MV v) = GM.mstreamR v 79 | #-} 80 | 81 | munboxed :: U.Unbox a => U.MVector s a -> MVector s a 82 | munboxed = MV 83 | 84 | mboxed :: BM.MVector s a -> MVector s a 85 | mboxed = MV 86 | 87 | unboxed :: U.Unbox a => U.Vector a -> Vector a 88 | unboxed = V 89 | 90 | boxed :: B.Vector a -> Vector a 91 | boxed = V 92 | 93 | newtype Id a = Id { runId :: a } 94 | 95 | cast2 :: (Typeable p, Typeable q) => p a b -> Maybe (q a b) 96 | cast2 x = runId <$> gcast2 (Id x) 97 | {-# INLINE cast2 #-} 98 | 99 | instance GM.MVector MVector a where 100 | basicLength (MV ks) = GM.basicLength ks 101 | {-# INLINE basicLength #-} 102 | basicUnsafeSlice s e (MV ks) = MV (GM.basicUnsafeSlice s e ks) 103 | {-# INLINE basicUnsafeSlice #-} 104 | basicOverlaps (MV as) (MV bs) = case cast2 as of 105 | Nothing -> True -- False could allow a composite vector that _does_ overlap internally to slip through! 106 | Just cs -> GM.basicOverlaps cs bs 107 | {-# INLINE basicOverlaps #-} 108 | basicUnsafeNew n = liftM mboxed (GM.basicUnsafeNew n) 109 | {-# INLINE basicUnsafeNew #-} 110 | basicUnsafeReplicate n k = liftM mboxed (GM.basicUnsafeReplicate n k) 111 | {-# INLINE basicUnsafeReplicate #-} 112 | basicUnsafeRead (MV ks) n = GM.basicUnsafeRead ks n 113 | {-# INLINE basicUnsafeRead #-} 114 | basicUnsafeWrite (MV ks) n k = GM.basicUnsafeWrite ks n k 115 | {-# INLINE basicUnsafeWrite #-} 116 | basicClear (MV ks) = GM.basicClear ks 117 | {-# INLINE basicClear #-} 118 | basicSet (MV ks) k = GM.basicSet ks k 119 | {-# INLINE basicSet #-} 120 | basicUnsafeCopy (MV dst) (MV src) = case cast2 dst of 121 | Nothing -> go 0 122 | Just dst' -> GM.basicUnsafeCopy dst' src -- the types match, allow fast copy 123 | where 124 | n = GM.basicLength src 125 | go i 126 | | i < n = do 127 | x <- GM.basicUnsafeRead src i 128 | GM.basicUnsafeWrite dst i x 129 | go (i+1) 130 | | otherwise = return () 131 | {-# INLINE basicUnsafeCopy #-} 132 | 133 | basicUnsafeMove (MV dst) (MV src) = case cast2 dst of 134 | Just dst' -> GM.basicUnsafeMove dst' src 135 | Nothing -> do 136 | srcCopy <- GM.munstream (GM.mstream src) 137 | GM.basicUnsafeCopy dst srcCopy 138 | {-# INLINE basicUnsafeMove #-} 139 | 140 | basicUnsafeGrow (MV ks) n = liftM MV (GM.basicUnsafeGrow ks n) 141 | {-# INLINE basicUnsafeGrow #-} 142 | 143 | -- mixed vectors 144 | data Vector :: * -> * where 145 | V :: Mixed mv v a => !(v a) -> Vector a 146 | 147 | {-# RULES 148 | "stream/V" forall v. 149 | G.stream (V v) = G.stream v 150 | "streamR/V" forall v. 151 | G.streamR (V v) = G.streamR v 152 | #-} 153 | 154 | type instance G.Mutable Vector = MVector 155 | 156 | instance G.Vector Vector a where 157 | basicUnsafeFreeze (MV ks) = liftM V (G.basicUnsafeFreeze ks) 158 | {-# INLINE basicUnsafeFreeze #-} 159 | basicUnsafeThaw (V ks) = liftM MV (G.basicUnsafeThaw ks) 160 | {-# INLINE basicUnsafeThaw #-} 161 | basicLength (V ks) = G.basicLength ks 162 | {-# INLINE basicLength #-} 163 | basicUnsafeSlice i j (V ks) = V (G.basicUnsafeSlice i j ks) 164 | {-# INLINE basicUnsafeSlice #-} 165 | basicUnsafeIndexM (V ks) n = G.basicUnsafeIndexM ks n 166 | {-# INLINE basicUnsafeIndexM #-} 167 | basicUnsafeCopy (MV dst) (V src) = case cast2 dst of 168 | Just dst' -> G.basicUnsafeCopy dst' src 169 | Nothing -> go 0 170 | where 171 | !n = G.basicLength src 172 | go i 173 | | i < n = do 174 | x <- G.basicUnsafeIndexM src i 175 | GM.basicUnsafeWrite dst i x 176 | go (i+1) 177 | | otherwise = return () 178 | {-# INLINE basicUnsafeCopy #-} 179 | elemseq (V ks) k b = G.elemseq ks k b 180 | {-# INLINE elemseq #-} 181 | 182 | instance Monoid (Vector a) where 183 | mappend = (G.++) 184 | {-# INLINE mappend #-} 185 | mempty = G.empty 186 | {-# INLINE mempty #-} 187 | mconcat = G.concat 188 | {-# INLINE mconcat #-} 189 | 190 | instance Show a => Show (Vector a) where 191 | showsPrec = G.showsPrec 192 | 193 | instance Read a => Read (Vector a) where 194 | readPrec = G.readPrec 195 | readListPrec = readListPrecDefault 196 | 197 | instance Data a => Data (Vector a) where 198 | gfoldl = G.gfoldl 199 | toConstr _ = error "toConstr" -- TODO: virtual constructor 200 | gunfold _ _ = error "gunfold" -- TODO: virtual constructor 201 | dataTypeOf _ = G.mkType "Data.Vector.Mixed.Vector" 202 | dataCast1 = G.dataCast 203 | 204 | instance Eq a => Eq (Vector a) where 205 | xs == ys = Stream.eq (G.stream xs) (G.stream ys) 206 | {-# INLINE (==) #-} 207 | 208 | xs /= ys = not (Stream.eq (G.stream xs) (G.stream ys)) 209 | {-# INLINE (/=) #-} 210 | 211 | 212 | -- See http://trac.haskell.org/vector/ticket/12 213 | instance Ord a => Ord (Vector a) where 214 | compare xs ys = Stream.cmp (G.stream xs) (G.stream ys) 215 | {-# INLINE compare #-} 216 | 217 | xs < ys = Stream.cmp (G.stream xs) (G.stream ys) == LT 218 | {-# INLINE (<) #-} 219 | 220 | xs <= ys = Stream.cmp (G.stream xs) (G.stream ys) /= GT 221 | {-# INLINE (<=) #-} 222 | 223 | xs > ys = Stream.cmp (G.stream xs) (G.stream ys) == GT 224 | {-# INLINE (>) #-} 225 | 226 | xs >= ys = Stream.cmp (G.stream xs) (G.stream ys) /= LT 227 | {-# INLINE (>=) #-} 228 | 229 | instance Functor Vector where 230 | fmap = G.map 231 | {-# INLINE fmap #-} 232 | 233 | instance Monad Vector where 234 | return = G.singleton 235 | {-# INLINE return #-} 236 | 237 | (>>=) = flip G.concatMap 238 | {-# INLINE (>>=) #-} 239 | 240 | instance MonadPlus Vector where 241 | {-# INLINE mzero #-} 242 | mzero = G.empty 243 | 244 | {-# INLINE mplus #-} 245 | mplus = (G.++) 246 | 247 | instance Applicative Vector where 248 | pure = G.singleton 249 | {-# INLINE pure #-} 250 | 251 | (<*>) = ap 252 | {-# INLINE (<*>) #-} 253 | 254 | instance Alternative Vector where 255 | empty = G.empty 256 | {-# INLINE empty #-} 257 | 258 | (<|>) = (G.++) 259 | {-# INLINE (<|>) #-} 260 | 261 | instance Foldable Vector where 262 | foldr = G.foldr 263 | {-# INLINE foldr #-} 264 | 265 | foldl = G.foldl 266 | {-# INLINE foldl #-} 267 | 268 | foldr1 = G.foldr1 269 | {-# INLINE foldr1 #-} 270 | 271 | foldl1 = G.foldl1 272 | {-# INLINE foldl1 #-} 273 | 274 | instance Traversable Vector where 275 | traverse f v = G.fromListN (G.length v) <$> traverse f (G.toList v) 276 | {-# INLINE traverse #-} 277 | -------------------------------------------------------------------------------- /src/Data/Vector/Mixed/Mutable.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 3 | {-# LANGUAGE KindSignatures #-} 4 | {-# LANGUAGE GADTs #-} 5 | {-# LANGUAGE MultiParamTypeClasses #-} 6 | {-# LANGUAGE UndecidableInstances #-} 7 | {-# LANGUAGE FlexibleInstances #-} 8 | {-# LANGUAGE TypeFamilies #-} 9 | {-# LANGUAGE DeriveDataTypeable #-} 10 | {-# LANGUAGE ScopedTypeVariables #-} 11 | 12 | module Data.Vector.Mixed.Mutable 13 | ( MVector 14 | , IOVector 15 | , STVector 16 | 17 | -- * Accessors 18 | 19 | -- ** Length information 20 | , length, null 21 | 22 | -- ** Extracting subvectors 23 | , slice, init, tail, take, drop, splitAt 24 | , unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop 25 | 26 | -- ** Overlapping 27 | , overlaps 28 | 29 | -- * Construction 30 | , replicateM, move, unsafeMove 31 | 32 | -- ** Initialisation 33 | , new, unsafeNew, replicate, clone 34 | 35 | -- ** Growing 36 | , grow, unsafeGrow 37 | 38 | -- ** Restricting memory usage 39 | , clear 40 | 41 | -- * Accessing individual elements 42 | , read, write, swap 43 | , unsafeRead, unsafeWrite, unsafeSwap 44 | 45 | -- * Modifying vectors 46 | 47 | -- ** Filling and copying 48 | , set, copy, unsafeCopy 49 | 50 | ) where 51 | 52 | import Control.Monad (liftM) 53 | import Control.Monad.Primitive 54 | import qualified Data.Vector.Generic.Mutable as G 55 | import Data.Vector.Mixed.Internal 56 | import Prelude hiding (length, null, replicate, reverse, map, read, take, drop, init, tail, splitAt) 57 | 58 | type IOVector = MVector RealWorld 59 | 60 | type STVector = MVector 61 | 62 | -- Length information 63 | -- ------------------ 64 | 65 | -- | Length of the mutable vector. 66 | length :: G.MVector u a => u s a -> Int 67 | length = G.length 68 | {-# INLINE length #-} 69 | 70 | -- | Check whether the vector is empty 71 | null :: G.MVector u a => u s a -> Bool 72 | null = G.null 73 | {-# INLINE null #-} 74 | 75 | -- Extracting subvectors 76 | -- --------------------- 77 | 78 | -- | Yield a part of the mutable vector without copying it. 79 | slice :: Mixed u v a => Int -> Int -> u s a -> MVector s a 80 | slice i j m = mmix (G.slice i j m) 81 | {-# INLINE slice #-} 82 | 83 | take :: Mixed u v a => Int -> u s a -> MVector s a 84 | take i m = mmix (G.take i m) 85 | {-# INLINE take #-} 86 | 87 | drop :: Mixed u v a => Int -> u s a -> MVector s a 88 | drop i m = mmix (G.drop i m) 89 | {-# INLINE drop #-} 90 | 91 | splitAt :: Mixed u v a => Int -> u s a -> (MVector s a, MVector s a) 92 | splitAt i m = case G.splitAt i m of 93 | (l,r) -> (mmix l, mmix r) 94 | {-# INLINE splitAt #-} 95 | 96 | init :: Mixed u v a => u s a -> MVector s a 97 | init m = mmix (G.init m) 98 | {-# INLINE init #-} 99 | 100 | tail :: Mixed u v a => u s a -> MVector s a 101 | tail m = mmix (G.tail m) 102 | {-# INLINE tail #-} 103 | 104 | -- | Yield a part of the mutable vector without copying it. No bounds checks 105 | -- are performed. 106 | unsafeSlice :: Mixed u v a => Int -- ^ starting index 107 | -> Int -- ^ length of the slice 108 | -> u s a 109 | -> MVector s a 110 | unsafeSlice i j m = mmix (G.unsafeSlice i j m) 111 | {-# INLINE unsafeSlice #-} 112 | 113 | unsafeTake :: Mixed u v a => Int -> u s a -> MVector s a 114 | unsafeTake i m = mmix (G.unsafeTake i m) 115 | {-# INLINE unsafeTake #-} 116 | 117 | unsafeDrop :: Mixed u v a => Int -> u s a -> MVector s a 118 | unsafeDrop i m = mmix (G.unsafeDrop i m) 119 | {-# INLINE unsafeDrop #-} 120 | 121 | unsafeInit :: Mixed u v a => u s a -> MVector s a 122 | unsafeInit m = mmix (G.unsafeInit m) 123 | {-# INLINE unsafeInit #-} 124 | 125 | unsafeTail :: Mixed u v a => u s a -> MVector s a 126 | unsafeTail m = mmix (G.unsafeTail m) 127 | {-# INLINE unsafeTail #-} 128 | 129 | -- Overlapping 130 | -- ----------- 131 | 132 | -- Check whether two vectors overlap. 133 | overlaps :: (Mixed u v a, Mixed u' v' a) => u s a -> u' s a -> Bool 134 | overlaps m n = G.overlaps (mmix m) (mmix n) 135 | {-# INLINE overlaps #-} 136 | 137 | -- Initialisation 138 | -- -------------- 139 | 140 | -- | Create a mutable vector of the given length. 141 | new :: PrimMonad m => Int -> m (MVector (PrimState m) a) 142 | new = G.new 143 | {-# INLINE new #-} 144 | 145 | -- | Create a mutable vector of the given length. The length is not checked. 146 | unsafeNew :: PrimMonad m => Int -> m (MVector (PrimState m) a) 147 | unsafeNew n = liftM mboxed (G.unsafeNew n) 148 | {-# INLINE unsafeNew #-} 149 | 150 | -- | Create a mutable vector of the given length (0 if the length is negative) 151 | -- and fill it with an initial value. 152 | replicate :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a) 153 | replicate n a = liftM mboxed (G.replicate n a) 154 | {-# INLINE replicate #-} 155 | 156 | -- | Create a mutable vector of the given length (0 if the length is negative) 157 | -- and fill it with values produced by repeatedly executing the monadic action. 158 | replicateM :: PrimMonad m => Int -> m a -> m (MVector (PrimState m) a) 159 | replicateM n m = liftM mboxed (G.replicateM n m) 160 | {-# INLINE replicateM #-} 161 | 162 | -- | Create a copy of a mutable vector. 163 | clone :: (PrimMonad m, Mixed u v a) => u (PrimState m) a -> m (MVector (PrimState m) a) 164 | clone m = liftM mmix (G.clone m) 165 | {-# INLINE clone #-} 166 | 167 | -- Growing 168 | -- ------- 169 | 170 | -- | Grow a vector by the given number of elements. The number must be 171 | -- positive. 172 | grow :: (PrimMonad m, Mixed u v a) => u (PrimState m) a -> Int -> m (MVector (PrimState m) a) 173 | grow m n = liftM mmix (G.grow m n) 174 | {-# INLINE grow #-} 175 | 176 | -- | Grow a vector by the given number of elements. The number must be 177 | -- positive but this is not checked. 178 | unsafeGrow :: (PrimMonad m, Mixed u v a) => u (PrimState m) a -> Int -> m (MVector (PrimState m) a) 179 | unsafeGrow m n = liftM mmix (G.unsafeGrow m n) 180 | {-# INLINE unsafeGrow #-} 181 | 182 | -- Restricting memory usage 183 | -- ------------------------ 184 | 185 | -- | Reset all elements of the vector to some undefined value, clearing all 186 | -- references to external objects. This is usually a noop for unboxed vectors. 187 | clear :: (PrimMonad m, G.MVector u a) => u (PrimState m) a -> m () 188 | clear = G.clear 189 | {-# INLINE clear #-} 190 | 191 | -- Accessing individual elements 192 | -- ----------------------------- 193 | 194 | -- | Yield the element at the given position. 195 | read :: (PrimMonad m, G.MVector u a) => u (PrimState m) a -> Int -> m a 196 | read = G.read 197 | {-# INLINE read #-} 198 | 199 | -- | Replace the element at the given position. 200 | write :: (PrimMonad m, G.MVector u a) => u (PrimState m) a -> Int -> a -> m () 201 | write = G.write 202 | {-# INLINE write #-} 203 | 204 | -- | Swap the elements at the given positions. 205 | swap :: (PrimMonad m, G.MVector u a) => u (PrimState m) a -> Int -> Int -> m () 206 | swap = G.swap 207 | {-# INLINE swap #-} 208 | 209 | 210 | -- | Yield the element at the given position. No bounds checks are performed. 211 | unsafeRead :: (PrimMonad m, G.MVector u a) => u (PrimState m) a -> Int -> m a 212 | unsafeRead = G.unsafeRead 213 | {-# INLINE unsafeRead #-} 214 | 215 | -- | Replace the element at the given position. No bounds checks are performed. 216 | unsafeWrite :: (PrimMonad m, G.MVector u a) => u (PrimState m) a -> Int -> a -> m () 217 | unsafeWrite = G.unsafeWrite 218 | {-# INLINE unsafeWrite #-} 219 | 220 | -- | Swap the elements at the given positions. No bounds checks are performed. 221 | unsafeSwap :: (PrimMonad m, G.MVector u a) => u (PrimState m) a -> Int -> Int -> m () 222 | unsafeSwap = G.unsafeSwap 223 | {-# INLINE unsafeSwap #-} 224 | 225 | -- Filling and copying 226 | -- ------------------- 227 | 228 | -- | Set all elements of the vector to the given value. 229 | set :: (PrimMonad m, G.MVector u a) => u (PrimState m) a -> a -> m () 230 | set = G.set 231 | {-# INLINE set #-} 232 | 233 | -- | Copy a vector. The two vectors must have the same length and may not 234 | -- overlap. 235 | copy :: (PrimMonad m, Mixed u v a, Mixed u' v' a) => u (PrimState m) a -> u' (PrimState m) a -> m () 236 | copy dst src = G.copy (mmix dst) (mmix src) 237 | {-# INLINE copy #-} 238 | 239 | -- | Copy a vector. The two vectors must have the same length and may not 240 | -- overlap. This is not checked. 241 | unsafeCopy 242 | :: (PrimMonad m, Mixed u v a, Mixed u' v' a) 243 | => u (PrimState m) a -- ^ target 244 | -> u' (PrimState m) a -- ^ source 245 | -> m () 246 | unsafeCopy dst src = G.unsafeCopy (mmix dst) (mmix src) 247 | {-# INLINE unsafeCopy #-} 248 | 249 | -- | Move the contents of a vector. The two vectors must have the same 250 | -- length. 251 | -- 252 | -- If the vectors do not overlap, then this is equivalent to 'copy'. 253 | -- Otherwise, the copying is performed as if the source vector were 254 | -- copied to a temporary vector and then the temporary vector was copied 255 | -- to the target vector. 256 | move :: (PrimMonad m, Mixed u v a, Mixed u' v' a) => u (PrimState m) a -> u' (PrimState m) a -> m () 257 | move dst src = G.move (mmix dst) (mmix src) 258 | {-# INLINE move #-} 259 | 260 | -- | Move the contents of a vector. The two vectors must have the same 261 | -- length, but this is not checked. 262 | -- 263 | -- If the vectors do not overlap, then this is equivalent to 'unsafeCopy'. 264 | -- Otherwise, the copying is performed as if the source vector were 265 | -- copied to a temporary vector and then the temporary vector was copied 266 | -- to the target vector. 267 | unsafeMove :: (PrimMonad m, Mixed u v a, Mixed u' v' a) 268 | => u (PrimState m) a -- ^ target 269 | -> u' (PrimState m) a -- ^ source 270 | -> m () 271 | unsafeMove dst src = G.unsafeMove (mmix dst) (mmix src) 272 | {-# INLINE unsafeMove #-} 273 | -------------------------------------------------------------------------------- /src/Data/Vector/Hybrid/Mutable.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 3 | {-# LANGUAGE KindSignatures #-} 4 | {-# LANGUAGE GADTs #-} 5 | {-# LANGUAGE MultiParamTypeClasses #-} 6 | {-# LANGUAGE UndecidableInstances #-} 7 | {-# LANGUAGE FlexibleInstances #-} 8 | {-# LANGUAGE TypeFamilies #-} 9 | {-# LANGUAGE DeriveDataTypeable #-} 10 | {-# LANGUAGE ScopedTypeVariables #-} 11 | 12 | module Data.Vector.Hybrid.Mutable 13 | ( MVector 14 | , IOVector 15 | , STVector 16 | 17 | -- * Accessors 18 | 19 | -- ** Length information 20 | , length, null 21 | 22 | -- ** Extracting subvectors 23 | , slice, init, tail, take, drop 24 | , unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop 25 | 26 | -- ** Overlapping 27 | , overlaps 28 | 29 | -- * Construction 30 | 31 | -- ** Initialisation 32 | , new, unsafeNew, replicate, clone 33 | 34 | -- ** Growing 35 | , grow, unsafeGrow 36 | 37 | -- ** Restricting memory usage 38 | , clear 39 | 40 | -- * Accessing individual elements 41 | , read, write, swap 42 | , unsafeRead, unsafeWrite, unsafeSwap 43 | 44 | -- * Modifying vectors 45 | 46 | -- ** Filling and copying 47 | , set, copy, unsafeCopy 48 | 49 | -- * Unsafe Construction and deconstruction 50 | , unsafeZip, projectFst, projectSnd 51 | 52 | -- * Deprecated operations 53 | , newWith, unsafeNewWith 54 | ) where 55 | 56 | import Control.Monad.Primitive 57 | import qualified Data.Vector.Generic.Mutable as G 58 | import Data.Vector.Hybrid.Internal 59 | import Prelude hiding ( length, null, replicate, reverse, map, read, take, drop, init, tail ) 60 | 61 | type IOVector u v = MVector u v RealWorld 62 | 63 | type STVector = MVector 64 | 65 | -- Length information 66 | -- ------------------ 67 | 68 | -- | Length of the mutable vector. 69 | length :: G.MVector u a => MVector u v s (a, b) -> Int 70 | length (MV ks _) = G.length ks 71 | {-# INLINE length #-} 72 | 73 | -- | Check whether the vector is empty 74 | null :: G.MVector u a => MVector u v s (a, b) -> Bool 75 | null (MV ks _) = G.null ks 76 | {-# INLINE null #-} 77 | 78 | -- Extracting subvectors 79 | -- --------------------- 80 | 81 | -- | Yield a part of the mutable vector without copying it. 82 | slice :: (G.MVector u a, G.MVector v b) => Int -> Int -> MVector u v s (a, b) -> MVector u v s (a, b) 83 | slice = G.slice 84 | {-# INLINE slice #-} 85 | 86 | take :: (G.MVector u a, G.MVector v b) => Int -> MVector u v s (a, b) -> MVector u v s (a, b) 87 | take = G.take 88 | {-# INLINE take #-} 89 | 90 | drop :: (G.MVector u a, G.MVector v b) => Int -> MVector u v s (a, b) -> MVector u v s (a, b) 91 | drop = G.drop 92 | {-# INLINE drop #-} 93 | 94 | init :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) 95 | init = G.init 96 | {-# INLINE init #-} 97 | 98 | tail :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) 99 | tail = G.tail 100 | {-# INLINE tail #-} 101 | 102 | -- | Yield a part of the mutable vector without copying it. No bounds checks 103 | -- are performed. 104 | unsafeSlice :: (G.MVector u a, G.MVector v b) 105 | => Int -- ^ starting index 106 | -> Int -- ^ length of the slice 107 | -> MVector u v s (a, b) 108 | -> MVector u v s (a, b) 109 | unsafeSlice = G.unsafeSlice 110 | {-# INLINE unsafeSlice #-} 111 | 112 | unsafeTake :: (G.MVector u a, G.MVector v b) => Int -> MVector u v s (a, b) -> MVector u v s (a, b) 113 | unsafeTake = G.unsafeTake 114 | {-# INLINE unsafeTake #-} 115 | 116 | unsafeDrop :: (G.MVector u a, G.MVector v b) => Int -> MVector u v s (a, b) -> MVector u v s (a, b) 117 | unsafeDrop = G.unsafeDrop 118 | {-# INLINE unsafeDrop #-} 119 | 120 | unsafeInit :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) 121 | unsafeInit = G.unsafeInit 122 | {-# INLINE unsafeInit #-} 123 | 124 | unsafeTail :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) 125 | unsafeTail = G.unsafeTail 126 | {-# INLINE unsafeTail #-} 127 | 128 | -- Overlapping 129 | -- ----------- 130 | 131 | -- Check whether two vectors overlap. 132 | overlaps :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) -> Bool 133 | overlaps = G.overlaps 134 | {-# INLINE overlaps #-} 135 | 136 | -- Initialisation 137 | -- -------------- 138 | 139 | -- | Create a mutable vector of the given length. 140 | new :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> m (MVector u v (PrimState m) (a, b)) 141 | new = G.new 142 | {-# INLINE new #-} 143 | 144 | -- | Create a mutable vector of the given length. The length is not checked. 145 | unsafeNew :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> m (MVector u v (PrimState m) (a, b)) 146 | unsafeNew = G.unsafeNew 147 | {-# INLINE unsafeNew #-} 148 | 149 | -- | Create a mutable vector of the given length (0 if the length is negative) 150 | -- and fill it with an initial value. 151 | replicate :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> (a, b) -> m (MVector u v (PrimState m) (a, b)) 152 | replicate = G.replicate 153 | {-# INLINE replicate #-} 154 | 155 | -- | Create a copy of a mutable vector. 156 | clone :: (PrimMonad m, G.MVector u a, G.MVector v b) 157 | => MVector u v (PrimState m) (a, b) -> m (MVector u v (PrimState m) (a, b)) 158 | clone = G.clone 159 | {-# INLINE clone #-} 160 | 161 | -- Growing 162 | -- ------- 163 | 164 | -- | Grow a vector by the given number of elements. The number must be 165 | -- positive. 166 | grow :: (PrimMonad m, G.MVector u a, G.MVector v b) 167 | => MVector u v (PrimState m) (a, b) -> Int -> m (MVector u v (PrimState m) (a, b)) 168 | grow = G.grow 169 | {-# INLINE grow #-} 170 | 171 | -- | Grow a vector by the given number of elements. The number must be 172 | -- positive but this is not checked. 173 | unsafeGrow :: (PrimMonad m, G.MVector u a, G.MVector v b) 174 | => MVector u v (PrimState m) (a, b) -> Int -> m (MVector u v (PrimState m) (a, b)) 175 | unsafeGrow = G.unsafeGrow 176 | {-# INLINE unsafeGrow #-} 177 | 178 | -- Restricting memory usage 179 | -- ------------------------ 180 | 181 | -- | Reset all elements of the vector to some undefined value, clearing all 182 | -- references to external objects. This is usually a noop for unboxed vectors. 183 | clear :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> m () 184 | clear = G.clear 185 | {-# INLINE clear #-} 186 | 187 | -- Accessing individual elements 188 | -- ----------------------------- 189 | 190 | -- | Yield the element at the given position. 191 | read :: (PrimMonad m, G.MVector u a, G.MVector v b) 192 | => MVector u v (PrimState m) (a, b) -> Int -> m (a, b) 193 | read = G.read 194 | {-# INLINE read #-} 195 | 196 | -- | Replace the element at the given position. 197 | write :: (PrimMonad m, G.MVector u a, G.MVector v b) 198 | => MVector u v (PrimState m) (a, b) -> Int -> (a, b) -> m () 199 | write = G.write 200 | {-# INLINE write #-} 201 | 202 | -- | Swap the elements at the given positions. 203 | swap :: (PrimMonad m, G.MVector u a, G.MVector v b) 204 | => MVector u v (PrimState m) (a, b) -> Int -> Int -> m () 205 | swap = G.swap 206 | {-# INLINE swap #-} 207 | 208 | 209 | -- | Yield the element at the given position. No bounds checks are performed. 210 | unsafeRead :: (PrimMonad m, G.MVector u a, G.MVector v b) 211 | => MVector u v (PrimState m) (a, b) -> Int -> m (a, b) 212 | unsafeRead = G.unsafeRead 213 | {-# INLINE unsafeRead #-} 214 | 215 | -- | Replace the element at the given position. No bounds checks are performed. 216 | unsafeWrite :: (PrimMonad m, G.MVector u a, G.MVector v b) 217 | => MVector u v (PrimState m) (a, b) -> Int -> (a, b) -> m () 218 | unsafeWrite = G.unsafeWrite 219 | {-# INLINE unsafeWrite #-} 220 | 221 | -- | Swap the elements at the given positions. No bounds checks are performed. 222 | unsafeSwap 223 | :: (PrimMonad m, G.MVector u a, G.MVector v b) 224 | => MVector u v (PrimState m) (a, b) -> Int -> Int -> m () 225 | unsafeSwap = G.unsafeSwap 226 | {-# INLINE unsafeSwap #-} 227 | 228 | -- Filling and copying 229 | -- ------------------- 230 | 231 | -- | Set all elements of the vector to the given value. 232 | set :: (PrimMonad m, G.MVector u a, G.MVector v b) 233 | => MVector u v (PrimState m) (a, b) -> (a, b) -> m () 234 | set = G.set 235 | {-# INLINE set #-} 236 | 237 | -- | Copy a vector. The two vectors must have the same length and may not 238 | -- overlap. 239 | copy :: (PrimMonad m, G.MVector u a, G.MVector v b) 240 | => MVector u v (PrimState m) (a, b) -> MVector u v (PrimState m) (a, b) -> m () 241 | copy = G.copy 242 | {-# INLINE copy #-} 243 | 244 | -- | Copy a vector. The two vectors must have the same length and may not 245 | -- overlap. This is not checked. 246 | unsafeCopy :: (PrimMonad m, G.MVector u a, G.MVector v b) 247 | => MVector u v (PrimState m) (a, b) -- ^ target 248 | -> MVector u v (PrimState m) (a, b) -- ^ source 249 | -> m () 250 | {-# INLINE unsafeCopy #-} 251 | unsafeCopy = G.unsafeCopy 252 | 253 | -- Unsafe composition and decomposition 254 | -- ------------------------------------ 255 | 256 | -- | The mutable vectors are assumed to be of the same length and to not overlap. This is not checked. 257 | unsafeZip :: u s a -> v s b -> MVector u v s (a, b) 258 | unsafeZip = MV 259 | {-# INLINE unsafeZip #-} 260 | 261 | projectFst :: MVector u v s (a, b) -> u s a 262 | projectFst (MV ks _) = ks 263 | {-# INLINE projectFst #-} 264 | 265 | projectSnd :: MVector u v s (a, b) -> v s b 266 | projectSnd (MV _ vs) = vs 267 | {-# INLINE projectSnd #-} 268 | 269 | -- Deprecated functions 270 | -- -------------------- 271 | 272 | -- | /DEPRECATED/ Use 'replicate' instead 273 | newWith :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> (a, b) -> m (MVector u v (PrimState m) (a, b)) 274 | newWith = G.replicate 275 | {-# INLINE newWith #-} 276 | 277 | -- | /DEPRECATED/ Use 'replicate' instead 278 | unsafeNewWith :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> (a, b) -> m (MVector u v (PrimState m) (a, b)) 279 | unsafeNewWith = G.replicate 280 | {-# INLINE unsafeNewWith #-} 281 | 282 | {-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-} 283 | -------------------------------------------------------------------------------- /.github/workflows/haskell-ci.yml: -------------------------------------------------------------------------------- 1 | # This GitHub workflow config has been generated by a script via 2 | # 3 | # haskell-ci 'github' 'cabal.project' 4 | # 5 | # To regenerate the script (for example after adjusting tested-with) run 6 | # 7 | # haskell-ci regenerate 8 | # 9 | # For more information, see https://github.com/haskell-CI/haskell-ci 10 | # 11 | # version: 0.19.20250821 12 | # 13 | # REGENDATA ("0.19.20250821",["github","cabal.project"]) 14 | # 15 | name: Haskell-CI 16 | on: 17 | - push 18 | - pull_request 19 | jobs: 20 | linux: 21 | name: Haskell-CI - Linux - ${{ matrix.compiler }} 22 | runs-on: ubuntu-24.04 23 | timeout-minutes: 24 | 60 25 | container: 26 | image: buildpack-deps:jammy 27 | continue-on-error: ${{ matrix.allow-failure }} 28 | strategy: 29 | matrix: 30 | include: 31 | - compiler: ghc-9.12.1 32 | compilerKind: ghc 33 | compilerVersion: 9.12.1 34 | setup-method: ghcup 35 | allow-failure: false 36 | - compiler: ghc-9.10.1 37 | compilerKind: ghc 38 | compilerVersion: 9.10.1 39 | setup-method: ghcup 40 | allow-failure: false 41 | - compiler: ghc-9.8.4 42 | compilerKind: ghc 43 | compilerVersion: 9.8.4 44 | setup-method: ghcup 45 | allow-failure: false 46 | - compiler: ghc-9.6.6 47 | compilerKind: ghc 48 | compilerVersion: 9.6.6 49 | setup-method: ghcup 50 | allow-failure: false 51 | - compiler: ghc-9.4.8 52 | compilerKind: ghc 53 | compilerVersion: 9.4.8 54 | setup-method: ghcup 55 | allow-failure: false 56 | - compiler: ghc-9.2.8 57 | compilerKind: ghc 58 | compilerVersion: 9.2.8 59 | setup-method: ghcup 60 | allow-failure: false 61 | - compiler: ghc-9.0.2 62 | compilerKind: ghc 63 | compilerVersion: 9.0.2 64 | setup-method: ghcup 65 | allow-failure: false 66 | - compiler: ghc-8.10.7 67 | compilerKind: ghc 68 | compilerVersion: 8.10.7 69 | setup-method: ghcup 70 | allow-failure: false 71 | - compiler: ghc-8.8.4 72 | compilerKind: ghc 73 | compilerVersion: 8.8.4 74 | setup-method: ghcup 75 | allow-failure: false 76 | - compiler: ghc-8.6.5 77 | compilerKind: ghc 78 | compilerVersion: 8.6.5 79 | setup-method: ghcup 80 | allow-failure: false 81 | - compiler: ghc-8.4.4 82 | compilerKind: ghc 83 | compilerVersion: 8.4.4 84 | setup-method: ghcup 85 | allow-failure: false 86 | - compiler: ghc-8.2.2 87 | compilerKind: ghc 88 | compilerVersion: 8.2.2 89 | setup-method: ghcup 90 | allow-failure: false 91 | - compiler: ghc-8.0.2 92 | compilerKind: ghc 93 | compilerVersion: 8.0.2 94 | setup-method: ghcup 95 | allow-failure: false 96 | fail-fast: false 97 | steps: 98 | - name: apt-get install 99 | run: | 100 | apt-get update 101 | apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5 libnuma-dev 102 | - name: Install GHCup 103 | run: | 104 | mkdir -p "$HOME/.ghcup/bin" 105 | curl -sL https://downloads.haskell.org/ghcup/0.1.50.1/x86_64-linux-ghcup-0.1.50.1 > "$HOME/.ghcup/bin/ghcup" 106 | chmod a+x "$HOME/.ghcup/bin/ghcup" 107 | - name: Install cabal-install 108 | run: | 109 | "$HOME/.ghcup/bin/ghcup" install cabal 3.16.0.0 || (cat "$HOME"/.ghcup/logs/*.* && false) 110 | echo "CABAL=$HOME/.ghcup/bin/cabal-3.16.0.0 -vnormal+nowrap" >> "$GITHUB_ENV" 111 | - name: Install GHC (GHCup) 112 | if: matrix.setup-method == 'ghcup' 113 | run: | 114 | "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false) 115 | HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER") 116 | HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#') 117 | HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#') 118 | echo "HC=$HC" >> "$GITHUB_ENV" 119 | echo "HCPKG=$HCPKG" >> "$GITHUB_ENV" 120 | echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV" 121 | env: 122 | HCKIND: ${{ matrix.compilerKind }} 123 | HCNAME: ${{ matrix.compiler }} 124 | HCVER: ${{ matrix.compilerVersion }} 125 | - name: Set PATH and environment variables 126 | run: | 127 | echo "$HOME/.cabal/bin" >> $GITHUB_PATH 128 | echo "LANG=C.UTF-8" >> "$GITHUB_ENV" 129 | echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV" 130 | echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV" 131 | HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))') 132 | echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV" 133 | echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV" 134 | echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV" 135 | echo "HEADHACKAGE=false" >> "$GITHUB_ENV" 136 | echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV" 137 | env: 138 | HCKIND: ${{ matrix.compilerKind }} 139 | HCNAME: ${{ matrix.compiler }} 140 | HCVER: ${{ matrix.compilerVersion }} 141 | - name: env 142 | run: | 143 | env 144 | - name: write cabal config 145 | run: | 146 | mkdir -p $CABAL_DIR 147 | cat >> $CABAL_CONFIG <> $CABAL_CONFIG < cabal-plan.xz 180 | echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c - 181 | xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan 182 | rm -f cabal-plan.xz 183 | chmod a+x $HOME/.cabal/bin/cabal-plan 184 | cabal-plan --version 185 | - name: checkout 186 | uses: actions/checkout@v4 187 | with: 188 | path: source 189 | - name: initial cabal.project for sdist 190 | run: | 191 | touch cabal.project 192 | echo "packages: $GITHUB_WORKSPACE/source/." >> cabal.project 193 | cat cabal.project 194 | - name: sdist 195 | run: | 196 | mkdir -p sdist 197 | $CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist 198 | - name: unpack 199 | run: | 200 | mkdir -p unpacked 201 | find sdist -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C $GITHUB_WORKSPACE/unpacked -xzvf {} \; 202 | - name: generate cabal.project 203 | run: | 204 | PKGDIR_hybrid_vectors="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/hybrid-vectors-[0-9.]*')" 205 | echo "PKGDIR_hybrid_vectors=${PKGDIR_hybrid_vectors}" >> "$GITHUB_ENV" 206 | rm -f cabal.project cabal.project.local 207 | touch cabal.project 208 | touch cabal.project.local 209 | echo "packages: ${PKGDIR_hybrid_vectors}" >> cabal.project 210 | if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo "package hybrid-vectors" >> cabal.project ; fi 211 | if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods -Werror=missing-fields" >> cabal.project ; fi 212 | if [ $((HCNUMVER >= 90400)) -ne 0 ] ; then echo "package hybrid-vectors" >> cabal.project ; fi 213 | if [ $((HCNUMVER >= 90400)) -ne 0 ] ; then echo " ghc-options: -Werror=unused-packages" >> cabal.project ; fi 214 | if [ $((HCNUMVER >= 90000)) -ne 0 ] ; then echo "package hybrid-vectors" >> cabal.project ; fi 215 | if [ $((HCNUMVER >= 90000)) -ne 0 ] ; then echo " ghc-options: -Werror=incomplete-patterns -Werror=incomplete-uni-patterns" >> cabal.project ; fi 216 | cat >> cabal.project <> cabal.project.local 219 | cat cabal.project 220 | cat cabal.project.local 221 | - name: dump install plan 222 | run: | 223 | $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all 224 | cabal-plan 225 | - name: restore cache 226 | uses: actions/cache/restore@v4 227 | with: 228 | key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} 229 | path: ~/.cabal/store 230 | restore-keys: ${{ runner.os }}-${{ matrix.compiler }}- 231 | - name: install dependencies 232 | run: | 233 | $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all 234 | $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j2 all 235 | - name: build 236 | run: | 237 | $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always 238 | - name: cabal check 239 | run: | 240 | cd ${PKGDIR_hybrid_vectors} || false 241 | ${CABAL} -vnormal check 242 | - name: haddock 243 | run: | 244 | $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all 245 | - name: save cache 246 | if: always() 247 | uses: actions/cache/save@v4 248 | with: 249 | key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} 250 | path: ~/.cabal/store 251 | -------------------------------------------------------------------------------- /src/Data/Vector/Hybrid.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 2 | {-# LANGUAGE KindSignatures #-} 3 | {-# LANGUAGE GADTs #-} 4 | {-# LANGUAGE MultiParamTypeClasses #-} 5 | {-# LANGUAGE UndecidableInstances #-} 6 | {-# LANGUAGE FlexibleInstances #-} 7 | {-# LANGUAGE TypeFamilies #-} 8 | {-# LANGUAGE Rank2Types #-} 9 | ----------------------------------------------------------------------------- 10 | -- | 11 | -- Copyright : (C) 2011 Edward Kmett, 12 | -- License : BSD-style (see the file LICENSE) 13 | -- 14 | -- Maintainer : Edward Kmett 15 | -- Stability : experimental 16 | -- Portability : non-portable 17 | -- 18 | -- A hybrid 'Vector' lets you make a 'Vector' which is 'partially unboxed', by 19 | -- making a 'Vector' out of two other 'Vector' types and using each for its 20 | -- corresponding side of a 'Vector' of pairs. 21 | -- 22 | -- This enables you to work with a mixture of boxed and unboxed data when 23 | -- you go to use something @like vector-algorithms@ 24 | ----------------------------------------------------------------------------- 25 | module Data.Vector.Hybrid 26 | ( Vector, MVector 27 | 28 | -- * Accessors 29 | 30 | -- ** Length information 31 | , length, null 32 | 33 | -- ** Indexing 34 | , (!), (!?), head, last 35 | , unsafeIndex, unsafeHead, unsafeLast 36 | 37 | -- ** Monadic indexing 38 | , indexM, headM, lastM 39 | , unsafeIndexM, unsafeHeadM, unsafeLastM 40 | 41 | -- ** Extracting subvectors (slicing) 42 | , slice, init, tail, take, drop, splitAt 43 | , unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop 44 | 45 | -- * Construction 46 | 47 | -- ** Initialisation 48 | , empty, singleton, replicate, generate, iterateN 49 | 50 | -- ** Monadic initialisation 51 | , replicateM, generateM, create 52 | 53 | -- ** Unfolding 54 | , unfoldr, unfoldrN 55 | , constructN, constructrN 56 | 57 | -- -- ** Enumeration 58 | -- , enumFromN, enumFromStepN, enumFromTo, enumFromThenTo 59 | 60 | -- ** Concatenation 61 | , cons, snoc, (++), concat 62 | 63 | -- ** Restricting memory usage 64 | , force 65 | 66 | -- * Modifying vectors 67 | 68 | -- ** Bulk updates 69 | , (//) 70 | , unsafeUpd 71 | -- , update_, unsafeUpdate_ 72 | 73 | -- ** Accumulations 74 | , accum, unsafeAccum 75 | -- , accumulate_, unsafeAccumulate_ 76 | 77 | -- ** Permutations 78 | , reverse 79 | -- , backpermute, unsafeBackpermute 80 | 81 | -- ** Safe destructive updates 82 | , modify 83 | 84 | -- * Elementwise operations 85 | 86 | -- ** Mapping 87 | , map, imap, concatMap 88 | 89 | -- ** Monadic mapping 90 | , mapM, mapM_, forM, forM_ 91 | 92 | -- ** Zipping 93 | , zipWith, zipWith3, zipWith4, zipWith5, zipWith6 94 | , izipWith, izipWith3, izipWith4, izipWith5, izipWith6 95 | 96 | -- ** Monadic zipping 97 | , zipWithM, zipWithM_ 98 | 99 | -- * Working with predicates 100 | 101 | -- ** Filtering 102 | , filter, ifilter, filterM 103 | , takeWhile, dropWhile 104 | 105 | -- ** Partitioning 106 | , partition, unstablePartition, span, break 107 | 108 | -- ** Searching 109 | , elem, notElem, find, findIndex 110 | , elemIndex 111 | -- , findIndices, elemIndices 112 | 113 | -- * Folding 114 | , foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1' 115 | , ifoldl, ifoldl', ifoldr, ifoldr' 116 | 117 | -- ** Specialised folds 118 | , all, any 119 | -- , sum, product 120 | , maximum, maximumBy, minimum, minimumBy 121 | , minIndex, minIndexBy, maxIndex, maxIndexBy 122 | 123 | -- ** Monadic folds 124 | , foldM, foldM', fold1M, fold1M' 125 | , foldM_, foldM'_, fold1M_, fold1M'_ 126 | 127 | -- * Prefix sums (scans) 128 | , prescanl, prescanl' 129 | , postscanl, postscanl' 130 | , scanl, scanl', scanl1, scanl1' 131 | , prescanr, prescanr' 132 | , postscanr, postscanr' 133 | , scanr, scanr', scanr1, scanr1' 134 | 135 | -- * Conversions 136 | , projectFst 137 | , projectSnd 138 | , unsafeZip 139 | 140 | -- ** Lists 141 | , toList, fromList, fromListN 142 | 143 | -- ** Other vector types 144 | , G.convert 145 | 146 | -- ** Mutable vectors 147 | , freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy 148 | ) where 149 | 150 | import Control.Monad.Primitive 151 | import Control.Monad.ST 152 | import Data.Vector.Hybrid.Internal 153 | import qualified Data.Vector.Generic as G 154 | import Prelude (Int, Bool, Maybe, Monad, Ordering, Ord, Eq) 155 | 156 | 157 | -- Length 158 | -- ------ 159 | 160 | -- | /O(1)/ Yield the length of the vector. 161 | length :: G.Vector u a => Vector u v (a, b) -> Int 162 | length (V ks _) = G.length ks 163 | {-# INLINE length #-} 164 | 165 | -- | /O(1)/ Test whether a vector if empty 166 | null :: G.Vector u a => Vector u v (a, b) -> Bool 167 | null (V ks _) = G.null ks 168 | {-# INLINE null #-} 169 | 170 | 171 | -- Indexing 172 | -- -------- 173 | 174 | -- | O(1) Indexing 175 | (!) :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Int -> (a, b) 176 | (!) = (G.!) 177 | {-# INLINE (!) #-} 178 | 179 | -- | O(1) Safe indexing 180 | (!?) :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Int -> Maybe (a, b) 181 | (!?) = (G.!?) 182 | {-# INLINE (!?) #-} 183 | 184 | -- | /O(1)/ First element 185 | head :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> (a, b) 186 | head = G.head 187 | {-# INLINE head #-} 188 | 189 | -- | /O(1)/ Last element 190 | last :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> (a, b) 191 | last = G.last 192 | {-# INLINE last #-} 193 | 194 | 195 | -- | /O(1)/ Unsafe indexing without bounds checking 196 | unsafeIndex :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Int -> (a, b) 197 | {-# INLINE unsafeIndex #-} 198 | unsafeIndex = G.unsafeIndex 199 | 200 | -- | /O(1)/ First element without checking if the vector is empty 201 | unsafeHead :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> (a, b) 202 | {-# INLINE unsafeHead #-} 203 | unsafeHead = G.unsafeHead 204 | 205 | -- | /O(1)/ Last element without checking if the vector is empty 206 | unsafeLast :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> (a, b) 207 | {-# INLINE unsafeLast #-} 208 | unsafeLast = G.unsafeLast 209 | 210 | -- Monadic indexing 211 | -- ---------------- 212 | 213 | -- | /O(1)/ Indexing in a monad. 214 | -- 215 | -- The monad allows operations to be strict in the vector when necessary. 216 | -- Suppose vector copying is implemented like this: 217 | -- 218 | -- > copy mv v = ... write mv i (v ! i) ... 219 | -- 220 | -- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@ 221 | -- would unnecessarily retain a reference to @v@ in each element written. 222 | -- 223 | -- With 'indexM', copying can be implemented like this instead: 224 | -- 225 | -- > copy mv v = ... do 226 | -- > x <- indexM v i 227 | -- > write mv i x 228 | -- 229 | -- Here, no references to @v@ are retained because indexing (but /not/ the 230 | -- elements) is evaluated eagerly. 231 | -- 232 | indexM :: (G.Vector u a, G.Vector v b, Monad m) => Vector u v (a, b) -> Int -> m (a, b) 233 | indexM = G.indexM 234 | {-# INLINE indexM #-} 235 | 236 | -- | /O(1)/ First element of a vector in a monad. See 'indexM' for an 237 | -- explanation of why this is useful. 238 | headM :: (G.Vector u a, G.Vector v b, Monad m) => Vector u v (a, b) -> m (a, b) 239 | headM = G.headM 240 | {-# INLINE headM #-} 241 | 242 | -- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an 243 | -- explanation of why this is useful. 244 | lastM :: (G.Vector u a, G.Vector v b, Monad m) => Vector u v (a, b) -> m (a, b) 245 | lastM = G.lastM 246 | {-# INLINE lastM #-} 247 | 248 | -- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an 249 | -- explanation of why this is useful. 250 | unsafeIndexM :: (G.Vector u a, G.Vector v b, Monad m) => Vector u v (a, b) -> Int -> m (a, b) 251 | unsafeIndexM = G.unsafeIndexM 252 | {-# INLINE unsafeIndexM #-} 253 | 254 | -- | /O(1)/ First element in a monad without checking for empty vectors. 255 | -- See 'indexM' for an explanation of why this is useful. 256 | unsafeHeadM :: (G.Vector u a, G.Vector v b, Monad m) => Vector u v (a, b) -> m (a, b) 257 | unsafeHeadM = G.unsafeHeadM 258 | {-# INLINE unsafeHeadM #-} 259 | 260 | -- | /O(1)/ Last element in a monad without checking for empty vectors. 261 | -- See 'indexM' for an explanation of why this is useful. 262 | unsafeLastM :: (G.Vector u a, G.Vector v b, Monad m) => Vector u v (a, b) -> m (a, b) 263 | unsafeLastM = G.unsafeLastM 264 | {-# INLINE unsafeLastM #-} 265 | 266 | -- Extracting subvectors (slicing) 267 | -- ------------------------------- 268 | 269 | -- | /O(1)/ Yield a slice of the vector without copying it. The vector must 270 | -- contain at least @i+n@ elements. 271 | slice :: (G.Vector u a, G.Vector v b) 272 | => Int -- ^ @i@ starting index 273 | -> Int -- ^ @n@ length 274 | -> Vector u v (a, b) 275 | -> Vector u v (a, b) 276 | slice = G.slice 277 | {-# INLINE slice #-} 278 | 279 | -- | /O(1)/ Yield all but the last element without copying. The vector may not 280 | -- be empty. 281 | init :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Vector u v (a, b) 282 | init = G.init 283 | {-# INLINE init #-} 284 | 285 | -- | /O(1)/ Yield all but the first element without copying. The vector may not 286 | -- be empty. 287 | tail :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Vector u v (a, b) 288 | tail = G.tail 289 | {-# INLINE tail #-} 290 | 291 | -- | /O(1)/ Yield at the first @n@ elements without copying. The vector may 292 | -- contain less than @n@ elements in which case it is returned unchanged. 293 | take :: (G.Vector u a, G.Vector v b) => Int -> Vector u v (a, b) -> Vector u v (a, b) 294 | take = G.take 295 | {-# INLINE take #-} 296 | 297 | -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may 298 | -- contain less than @n@ elements in which case an empty vector is returned. 299 | drop :: (G.Vector u a, G.Vector v b) => Int -> Vector u v (a, b) -> Vector u v (a, b) 300 | drop = G.drop 301 | {-# INLINE drop #-} 302 | 303 | -- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying. 304 | -- 305 | -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ 306 | -- but slightly more efficient. 307 | splitAt :: (G.Vector u a, G.Vector v b) => Int -> Vector u v (a, b) -> (Vector u v (a, b), Vector u v (a, b)) 308 | splitAt = G.splitAt 309 | {-# INLINE splitAt #-} 310 | 311 | -- | /O(1)/ Yield a slice of the vector without copying. The vector must 312 | -- contain at least @i+n@ elements but this is not checked. 313 | unsafeSlice :: (G.Vector u a, G.Vector v b) => Int -- ^ @i@ starting index 314 | -> Int -- ^ @n@ length 315 | -> Vector u v (a, b) 316 | -> Vector u v (a, b) 317 | unsafeSlice = G.unsafeSlice 318 | {-# INLINE unsafeSlice #-} 319 | 320 | -- | /O(1)/ Yield all but the last element without copying. The vector may not 321 | -- be empty but this is not checked. 322 | unsafeInit :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Vector u v (a, b) 323 | unsafeInit = G.unsafeInit 324 | {-# INLINE unsafeInit #-} 325 | 326 | -- | /O(1)/ Yield all but the first element without copying. The vector may not 327 | -- be empty but this is not checked. 328 | unsafeTail :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Vector u v (a, b) 329 | unsafeTail = G.unsafeTail 330 | {-# INLINE unsafeTail #-} 331 | 332 | -- | /O(1)/ Yield the first @n@ elements without copying. The vector must 333 | -- contain at least @n@ elements but this is not checked. 334 | unsafeTake :: (G.Vector u a, G.Vector v b) => Int -> Vector u v (a, b) -> Vector u v (a, b) 335 | unsafeTake = G.unsafeTake 336 | {-# INLINE unsafeTake #-} 337 | 338 | -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector 339 | -- must contain at least @n@ elements but this is not checked. 340 | unsafeDrop :: (G.Vector u a, G.Vector v b) => Int -> Vector u v (a, b) -> Vector u v (a, b) 341 | unsafeDrop = G.unsafeDrop 342 | {-# INLINE unsafeDrop #-} 343 | 344 | -- Initialisation 345 | -- -------------- 346 | 347 | -- | /O(1)/ Empty vector 348 | empty :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) 349 | empty = G.empty 350 | {-# INLINE empty #-} 351 | 352 | -- | /O(1)/ Vector with exactly one element 353 | singleton :: (G.Vector u a, G.Vector v b) => (a, b) -> Vector u v (a, b) 354 | singleton = G.singleton 355 | {-# INLINE singleton #-} 356 | 357 | -- | /O(n)/ Vector of the given length with the same value in each position 358 | replicate :: (G.Vector u a, G.Vector v b) => Int -> (a, b) -> Vector u v (a, b) 359 | replicate = G.replicate 360 | {-# INLINE replicate #-} 361 | 362 | -- | /O(n)/ Construct a vector of the given length by applying the function to 363 | -- each index 364 | generate :: (G.Vector u a, G.Vector v b) => Int -> (Int -> (a, b)) -> Vector u v (a, b) 365 | generate = G.generate 366 | {-# INLINE generate #-} 367 | 368 | -- | /O(n)/ Apply function n times to value. Zeroth element is original value. 369 | iterateN :: (G.Vector u a, G.Vector v b) => Int -> ((a, b) -> (a, b)) -> (a, b) -> Vector u v (a, b) 370 | iterateN = G.iterateN 371 | {-# INLINE iterateN #-} 372 | 373 | -- Unfolding 374 | -- --------- 375 | 376 | -- | /O(n)/ Construct a vector by repeatedly applying the generator function 377 | -- to a seed. The generator function yields 'Just' the next element and the 378 | -- new seed or 'Nothing' if there are no more elements. 379 | -- 380 | -- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10 381 | -- > = <10,9,8,7,6,5,4,3,2,1> 382 | unfoldr :: (G.Vector u a, G.Vector v b) => (c -> Maybe ((a, b), c)) -> c -> Vector u v (a, b) 383 | unfoldr = G.unfoldr 384 | {-# INLINE unfoldr #-} 385 | 386 | -- | /O(n)/ Construct a vector with at most @n@ by repeatedly applying the 387 | -- generator function to the a seed. The generator function yields 'Just' the 388 | -- next element and the new seed or 'Nothing' if there are no more elements. 389 | -- 390 | -- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8> 391 | unfoldrN :: (G.Vector u a, G.Vector v b) => Int -> (c -> Maybe ((a, b), c)) -> c -> Vector u v (a, b) 392 | unfoldrN = G.unfoldrN 393 | {-# INLINE unfoldrN #-} 394 | 395 | -- | /O(n)/ Construct a vector with @n@ elements by repeatedly applying the 396 | -- generator function to the already constructed part of the vector. 397 | -- 398 | -- > constructN 3 f = let a = f <> ; b = f ; c = f in f 399 | -- 400 | constructN :: (G.Vector u a, G.Vector v b) => Int -> (Vector u v (a, b) -> (a, b)) -> Vector u v (a, b) 401 | constructN = G.constructN 402 | {-# INLINE constructN #-} 403 | 404 | -- | /O(n)/ Construct a vector with @n@ elements from right to left by 405 | -- repeatedly applying the generator function to the already constructed part 406 | -- of the vector. 407 | -- 408 | -- > constructrN 3 f = let a = f <> ; b = f ; c = f in f 409 | -- 410 | constructrN :: (G.Vector u a, G.Vector v b) => Int -> (Vector u v (a, b) -> (a, b)) -> Vector u v (a, b) 411 | constructrN = G.constructrN 412 | {-# INLINE constructrN #-} 413 | 414 | -- Concatenation 415 | -- ------------- 416 | 417 | -- | /O(n)/ Prepend an element 418 | cons :: (G.Vector u a, G.Vector v b) => (a, b) -> Vector u v (a, b) -> Vector u v (a, b) 419 | {-# INLINE cons #-} 420 | cons = G.cons 421 | 422 | -- | /O(n)/ Append an element 423 | snoc :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> (a, b) -> Vector u v (a, b) 424 | {-# INLINE snoc #-} 425 | snoc = G.snoc 426 | 427 | infixr 5 ++ 428 | -- | /O(m+n)/ Concatenate two vectors 429 | (++) :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Vector u v (a, b) -> Vector u v (a, b) 430 | {-# INLINE (++) #-} 431 | (++) = (G.++) 432 | 433 | -- | /O(n)/ Concatenate all vectors in the list 434 | concat :: (G.Vector u a, G.Vector v b) => [Vector u v (a, b)] -> Vector u v (a, b) 435 | {-# INLINE concat #-} 436 | concat = G.concat 437 | 438 | -- Monadic initialisation 439 | -- ---------------------- 440 | 441 | -- | /O(n)/ Execute the monadic action the given number of times and store the 442 | -- results in a vector. 443 | replicateM :: (Monad m, G.Vector u a, G.Vector v b) => Int -> m (a, b) -> m (Vector u v (a, b)) 444 | replicateM = G.replicateM 445 | {-# INLINE replicateM #-} 446 | 447 | -- | /O(n)/ Construct a vector of the given length by applying the monadic 448 | -- action to each index 449 | generateM :: (Monad m, G.Vector u a, G.Vector v b) => Int -> (Int -> m (a, b)) -> m (Vector u v (a, b)) 450 | generateM = G.generateM 451 | {-# INLINE generateM #-} 452 | 453 | -- | Execute the monadic action and freeze the resulting vector. 454 | -- 455 | -- @ 456 | -- create (do { v \<- new 2; write v 0 \'a\'; write v 1 \'b\'; return v }) = \<'a','b'\> 457 | -- @ 458 | create :: (G.Vector u a, G.Vector v b) => (forall s. ST s (G.Mutable (Vector u v) s (a, b))) -> Vector u v (a, b) 459 | -- NOTE: eta-expanded due to http://hackage.haskell.org/trac/ghc/ticket/4120 460 | create p = G.create p 461 | {-# INLINE create #-} 462 | 463 | -- Restricting memory usage 464 | -- ------------------------ 465 | 466 | -- | /O(n)/ Yield the argument but force it not to retain any extra memory, 467 | -- possibly by copying it. 468 | -- 469 | -- This is especially useful when dealing with slices. For example: 470 | -- 471 | -- > force (slice 0 2 ) 472 | -- 473 | -- Here, the slice retains a reference to the huge vector. Forcing it creates 474 | -- a copy of just the elements that belong to the slice and allows the huge 475 | -- vector to be garbage collected. 476 | force :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Vector u v (a, b) 477 | force = G.force 478 | {-# INLINE force #-} 479 | 480 | -- Bulk updates 481 | -- ------------ 482 | 483 | -- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector 484 | -- element at position @i@ by @a@. 485 | -- 486 | -- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7> 487 | -- 488 | (//) :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -- ^ initial vector (of length @m@) 489 | -> [(Int, (a, b))] -- ^ list of index/value pairs (of length @n@) 490 | -> Vector u v (a, b) 491 | (//) = (G.//) 492 | {-# INLINE (//) #-} 493 | 494 | -- | Same as ('//') but without bounds checking. 495 | unsafeUpd :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> [(Int, (a, b))] -> Vector u v (a, b) 496 | unsafeUpd = G.unsafeUpd 497 | {-# INLINE unsafeUpd #-} 498 | 499 | -- Accumulations 500 | -- ------------- 501 | 502 | -- | /O(m+n)/ For each pair @(i,c)@ from the list, replace the vector element 503 | -- @a@ at position @i@ by @f a c@. 504 | -- 505 | -- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4> 506 | accum :: (G.Vector u a, G.Vector v b) 507 | => ((a, b) -> c -> (a, b)) -- ^ accumulating function @f@ 508 | -> Vector u v (a, b) -- ^ initial vector (of length @m@) 509 | -> [(Int,c)] -- ^ list of index/value pairs (of length @n@) 510 | -> Vector u v (a, b) 511 | accum = G.accum 512 | {-# INLINE accum #-} 513 | 514 | -- | Same as 'accum' but without bounds checking. 515 | unsafeAccum :: (G.Vector u a, G.Vector v b) => ((a, b) -> c -> (a, b)) -> Vector u v (a, b) -> [(Int,c)] -> Vector u v (a, b) 516 | unsafeAccum = G.unsafeAccum 517 | {-# INLINE unsafeAccum #-} 518 | 519 | 520 | -- Permutations 521 | -- ------------ 522 | 523 | -- | /O(n)/ Reverse a vector 524 | reverse :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> Vector u v (a, b) 525 | {-# INLINE reverse #-} 526 | reverse = G.reverse 527 | 528 | -- Safe destructive updates 529 | -- ------------------------ 530 | 531 | -- | Apply a destructive operation to a vector. The operation will be 532 | -- performed in place if it is safe to do so and will modify a copy of the 533 | -- vector otherwise. 534 | -- 535 | -- @ 536 | -- modify (\\v -> write v 0 \'x\') ('replicate' 3 \'a\') = \<\'x\',\'a\',\'a\'\> 537 | -- @ 538 | modify :: (G.Vector u a, G.Vector v b) 539 | => (forall s. G.Mutable (Vector u v) s (a, b) -> ST s ()) 540 | -> Vector u v (a, b) -> Vector u v (a, b) 541 | {-# INLINE modify #-} 542 | modify p = G.modify p 543 | 544 | -- Mapping 545 | -- ------- 546 | 547 | -- | /O(n)/ Map a function over a vector 548 | map :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) 549 | => ((a, b) -> (c, d)) -> Vector u v (a, b) -> Vector u v (c, d) 550 | map = G.map 551 | {-# INLINE map #-} 552 | 553 | -- | /O(n)/ Apply a function to every element of a vector and its index 554 | imap :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) 555 | => (Int -> (a, b) -> (c, d)) 556 | -> Vector u v (a, b) -> Vector u v (c, d) 557 | imap = G.imap 558 | {-# INLINE imap #-} 559 | 560 | -- | Map a function over a vector and concatenate the results. 561 | concatMap :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) 562 | => ((a, b) -> Vector u v (c, d)) -> Vector u v (a, b) -> Vector u v (c, d) 563 | concatMap = G.concatMap 564 | {-# INLINE concatMap #-} 565 | 566 | -- Monadic mapping 567 | -- --------------- 568 | 569 | -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a 570 | -- vector of results 571 | mapM :: (Monad m, G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> m (c, d)) -> Vector u v (a, b) -> m (Vector u v (c, d)) 572 | mapM = G.mapM 573 | {-# INLINE mapM #-} 574 | 575 | -- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the 576 | -- results 577 | mapM_ :: (Monad m, G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> m (c, d)) -> Vector u v (a, b) -> m () 578 | mapM_ = G.mapM_ 579 | {-# INLINE mapM_ #-} 580 | 581 | -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a 582 | -- vector of results. Equvalent to @flip 'mapM'@. 583 | forM :: (Monad m, G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => Vector u v (a, b) -> ((a, b) -> m (c, d)) -> m (Vector u v (c, d)) 584 | forM = G.forM 585 | {-# INLINE forM #-} 586 | 587 | -- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the 588 | -- results. Equivalent to @flip 'mapM_'@. 589 | forM_ :: (Monad m, G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => Vector u v (a, b) -> ((a, b) -> m (c, d)) -> m () 590 | forM_ = G.forM_ 591 | {-# INLINE forM_ #-} 592 | 593 | -- Zipping 594 | -- ------- 595 | 596 | -- | /O(min(m,n))/ Zip two vectors with the given function. 597 | zipWith :: ( G.Vector u a, G.Vector v a' 598 | , G.Vector u b, G.Vector v b' 599 | , G.Vector u c, G.Vector v c' 600 | ) => ((a,a') -> (b,b') -> (c,c')) 601 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') 602 | zipWith = G.zipWith 603 | {-# INLINE zipWith #-} 604 | 605 | -- | Zip three vectors with the given function. 606 | 607 | zipWith3 :: ( G.Vector u a, G.Vector v a' 608 | , G.Vector u b, G.Vector v b' 609 | , G.Vector u c, G.Vector v c' 610 | , G.Vector u d, G.Vector v d' 611 | ) => ((a,a') -> (b,b') -> (c,c') -> (d, d')) 612 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') 613 | zipWith3 = G.zipWith3 614 | {-# INLINE zipWith3 #-} 615 | 616 | zipWith4 :: ( G.Vector u a, G.Vector v a' 617 | , G.Vector u b, G.Vector v b' 618 | , G.Vector u c, G.Vector v c' 619 | , G.Vector u d, G.Vector v d' 620 | , G.Vector u e, G.Vector v e' 621 | ) => ((a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e')) 622 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') 623 | zipWith4 = G.zipWith4 624 | {-# INLINE zipWith4 #-} 625 | 626 | zipWith5 :: ( G.Vector u a, G.Vector v a' 627 | , G.Vector u b, G.Vector v b' 628 | , G.Vector u c, G.Vector v c' 629 | , G.Vector u d, G.Vector v d' 630 | , G.Vector u e, G.Vector v e' 631 | , G.Vector u f, G.Vector v f' 632 | ) => ((a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f')) 633 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f') 634 | zipWith5 = G.zipWith5 635 | {-# INLINE zipWith5 #-} 636 | 637 | zipWith6 :: ( G.Vector u a, G.Vector v a' 638 | , G.Vector u b, G.Vector v b' 639 | , G.Vector u c, G.Vector v c' 640 | , G.Vector u d, G.Vector v d' 641 | , G.Vector u e, G.Vector v e' 642 | , G.Vector u f, G.Vector v f' 643 | , G.Vector u g, G.Vector v g' 644 | ) => ((a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f') -> (g,g')) 645 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f') -> Vector u v (g,g') 646 | zipWith6 = G.zipWith6 647 | {-# INLINE zipWith6 #-} 648 | 649 | -- | /O(min(m,n))/ Zip two vectors with a function that also takes the 650 | -- elements' indices. 651 | izipWith :: ( G.Vector u a, G.Vector v a' 652 | , G.Vector u b, G.Vector v b' 653 | , G.Vector u c, G.Vector v c' 654 | ) => (Int -> (a,a') -> (b,b') -> (c,c')) 655 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') 656 | izipWith = G.izipWith 657 | {-# INLINE izipWith #-} 658 | 659 | -- | Zip three vectors and their indices with the given function. 660 | izipWith3 :: ( G.Vector u a, G.Vector v a' 661 | , G.Vector u b, G.Vector v b' 662 | , G.Vector u c, G.Vector v c' 663 | , G.Vector u d, G.Vector v d' 664 | ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d')) 665 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') 666 | izipWith3 = G.izipWith3 667 | {-# INLINE izipWith3 #-} 668 | 669 | izipWith4 :: ( G.Vector u a, G.Vector v a' 670 | , G.Vector u b, G.Vector v b' 671 | , G.Vector u c, G.Vector v c' 672 | , G.Vector u d, G.Vector v d' 673 | , G.Vector u e, G.Vector v e' 674 | ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e')) 675 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') 676 | izipWith4 = G.izipWith4 677 | {-# INLINE izipWith4 #-} 678 | 679 | izipWith5 :: ( G.Vector u a, G.Vector v a' 680 | , G.Vector u b, G.Vector v b' 681 | , G.Vector u c, G.Vector v c' 682 | , G.Vector u d, G.Vector v d' 683 | , G.Vector u e, G.Vector v e' 684 | , G.Vector u f, G.Vector v f' 685 | ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f')) 686 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f') 687 | izipWith5 = G.izipWith5 688 | {-# INLINE izipWith5 #-} 689 | 690 | izipWith6 :: ( G.Vector u a, G.Vector v a' 691 | , G.Vector u b, G.Vector v b' 692 | , G.Vector u c, G.Vector v c' 693 | , G.Vector u d, G.Vector v d' 694 | , G.Vector u e, G.Vector v e' 695 | , G.Vector u f, G.Vector v f' 696 | , G.Vector u g, G.Vector v g' 697 | ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f') -> (g,g')) 698 | -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f') -> Vector u v (g,g') 699 | izipWith6 = G.izipWith6 700 | {-# INLINE izipWith6 #-} 701 | 702 | -- Monadic zipping 703 | -- --------------- 704 | 705 | -- | /O(min(m,n))/ Zip the two vectors with the monadic action and yield a 706 | -- vector of results 707 | zipWithM :: (Monad m, G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d, G.Vector u e, G.Vector v f) 708 | => ((a, b) -> (c, d) -> m (e,f)) -> Vector u v (a, b) -> Vector u v (c, d) -> m (Vector u v (e,f)) 709 | zipWithM = G.zipWithM 710 | {-# INLINE zipWithM #-} 711 | 712 | -- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the 713 | -- results 714 | zipWithM_ :: (Monad m, G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) 715 | => ((a, b) -> (c, d) -> m e) -> Vector u v (a, b) -> Vector u v (c, d) -> m () 716 | zipWithM_ = G.zipWithM_ 717 | {-# INLINE zipWithM_ #-} 718 | 719 | -- Filtering 720 | -- --------- 721 | 722 | -- | /O(n)/ Drop elements that do not satisfy the predicate 723 | filter :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> Vector u v (a, b) 724 | filter = G.filter 725 | {-# INLINE filter #-} 726 | 727 | -- | /O(n)/ Drop elements that do not satisfy the predicate which is applied to 728 | -- values and their indices 729 | ifilter :: (G.Vector u a, G.Vector v b) => (Int -> (a, b) -> Bool) -> Vector u v (a, b) -> Vector u v (a, b) 730 | ifilter = G.ifilter 731 | {-# INLINE ifilter #-} 732 | 733 | -- | /O(n)/ Drop elements that do not satisfy the monadic predicate 734 | filterM :: (Monad m, G.Vector u a, G.Vector v b) => ((a, b) -> m Bool) -> Vector u v (a, b) -> m (Vector u v (a, b)) 735 | filterM = G.filterM 736 | {-# INLINE filterM #-} 737 | 738 | -- | /O(n)/ Yield the longest prefix of elements satisfying the predicate 739 | -- without copying. 740 | takeWhile :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> Vector u v (a, b) 741 | takeWhile = G.takeWhile 742 | {-# INLINE takeWhile #-} 743 | 744 | -- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate 745 | -- without copying. 746 | dropWhile :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> Vector u v (a, b) 747 | dropWhile = G.dropWhile 748 | {-# INLINE dropWhile #-} 749 | 750 | 751 | -- Parititioning 752 | -- ------------- 753 | 754 | -- | /O(n)/ Split the vector in two parts, the first one containing those 755 | -- elements that satisfy the predicate and the second one those that don't. The 756 | -- relative order of the elements is preserved at the cost of a sometimes 757 | -- reduced performance compared to 'unstablePartition'. 758 | partition :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> (Vector u v (a, b), Vector u v (a, b)) 759 | {-# INLINE partition #-} 760 | partition = G.partition 761 | 762 | -- | /O(n)/ Split the vector in two parts, the first one containing those 763 | -- elements that satisfy the predicate and the second one those that don't. 764 | -- The order of the elements is not preserved but the operation is often 765 | -- faster than 'partition'. 766 | unstablePartition :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> (Vector u v (a, b), Vector u v (a, b)) 767 | {-# INLINE unstablePartition #-} 768 | unstablePartition = G.unstablePartition 769 | 770 | -- | /O(n)/ Split the vector into the longest prefix of elements that satisfy 771 | -- the predicate and the rest without copying. 772 | span :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> (Vector u v (a, b), Vector u v (a, b)) 773 | {-# INLINE span #-} 774 | span = G.span 775 | 776 | -- | /O(n)/ Split the vector into the longest prefix of elements that do not 777 | -- satisfy the predicate and the rest without copying. 778 | break :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> (Vector u v (a, b), Vector u v (a, b)) 779 | {-# INLINE break #-} 780 | break = G.break 781 | 782 | -- Searching 783 | -- --------- 784 | 785 | infix 4 `elem` 786 | -- | /O(n)/ Check if the vector contains an element 787 | elem :: (G.Vector u a, G.Vector v b, Eq a, Eq b) => (a, b) -> Vector u v (a, b) -> Bool 788 | elem = G.elem 789 | {-# INLINE elem #-} 790 | 791 | infix 4 `notElem` 792 | -- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem') 793 | notElem :: (G.Vector u a, G.Vector v b, Eq a, Eq b) => (a, b) -> Vector u v (a, b) -> Bool 794 | notElem = G.notElem 795 | {-# INLINE notElem #-} 796 | 797 | -- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing' 798 | -- if no such element exists. 799 | find :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> Maybe (a, b) 800 | find = G.find 801 | {-# INLINE find #-} 802 | 803 | -- | /O(n)/ Yield 'Just' the index of the first element matching the predicate 804 | -- or 'Nothing' if no such element exists. 805 | findIndex :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> Maybe Int 806 | findIndex = G.findIndex 807 | {-# INLINE findIndex #-} 808 | 809 | {- 810 | -- | /O(n)/ Yield the indices of elements satisfying the predicate in ascending 811 | -- order. 812 | findIndices :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> Vector u v Int 813 | findIndices = G.findIndices 814 | {-# INLINE findIndices #-} 815 | -} 816 | 817 | -- | /O(n)/ Yield 'Just' the index of the first occurence of the given element or 818 | -- 'Nothing' if the vector does not contain the element. This is a specialised 819 | -- version of 'findIndex'. 820 | elemIndex :: (G.Vector u a, G.Vector v b, Eq a, Eq b) => (a, b) -> Vector u v (a, b) -> Maybe Int 821 | elemIndex = G.elemIndex 822 | {-# INLINE elemIndex #-} 823 | 824 | {- 825 | -- | /O(n)/ Yield the indices of all occurences of the given element in 826 | -- ascending order. This is a specialised version of 'findIndices'. 827 | elemIndices :: (G.Vector u a, G.Vector v b, Eq a, Eq b) => (a, b) -> Vector u v (a, b) -> Vector Int 828 | elemIndices = G.elemIndices 829 | {-# INLINE elemIndices #-} 830 | -} 831 | 832 | -- Folding 833 | -- ------- 834 | 835 | -- | /O(n)/ Left fold 836 | foldl :: (G.Vector u a, G.Vector v b) => (r -> (a, b) -> r) -> r -> Vector u v (a, b) -> r 837 | foldl = G.foldl 838 | {-# INLINE foldl #-} 839 | 840 | -- | /O(n)/ Left fold on non-empty vectors 841 | foldl1 :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> (a, b)) -> Vector u v (a, b) -> (a, b) 842 | foldl1 = G.foldl1 843 | {-# INLINE foldl1 #-} 844 | 845 | -- | /O(n)/ Left fold with strict accumulator 846 | foldl' :: (G.Vector u a, G.Vector v b) => (r -> (a, b) -> r) -> r -> Vector u v (a, b) -> r 847 | foldl' = G.foldl' 848 | {-# INLINE foldl' #-} 849 | 850 | -- | /O(n)/ Left fold on non-empty vectors with strict accumulator 851 | foldl1' :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> (a, b)) -> Vector u v (a, b) -> (a, b) 852 | foldl1' = G.foldl1' 853 | {-# INLINE foldl1' #-} 854 | 855 | -- | /O(n)/ Right fold 856 | foldr :: (G.Vector u a, G.Vector v b) => ((a, b) -> r -> r) -> r -> Vector u v (a, b) -> r 857 | foldr = G.foldr 858 | {-# INLINE foldr #-} 859 | 860 | -- | /O(n)/ Right fold on non-empty vectors 861 | foldr1 :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> (a, b)) -> Vector u v (a, b) -> (a, b) 862 | foldr1 = G.foldr1 863 | {-# INLINE foldr1 #-} 864 | 865 | -- | /O(n)/ Right fold with a strict accumulator 866 | foldr' :: (G.Vector u a, G.Vector v b) => ((a, b) -> r -> r) -> r -> Vector u v (a, b) -> r 867 | foldr' = G.foldr' 868 | {-# INLINE foldr' #-} 869 | 870 | -- | /O(n)/ Right fold on non-empty vectors with strict accumulator 871 | foldr1' :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> (a, b)) -> Vector u v (a, b) -> (a, b) 872 | foldr1' = G.foldr1' 873 | {-# INLINE foldr1' #-} 874 | 875 | -- | /O(n)/ Left fold (function applied to each element and its index) 876 | ifoldl :: (G.Vector u a, G.Vector v b) => (r -> Int -> (a, b) -> r) -> r -> Vector u v (a, b) -> r 877 | ifoldl = G.ifoldl 878 | {-# INLINE ifoldl #-} 879 | 880 | -- | /O(n)/ Left fold with strict accumulator (function applied to each element 881 | -- and its index) 882 | ifoldl' :: (G.Vector u a, G.Vector v b) => (r -> Int -> (a, b) -> r) -> r -> Vector u v (a, b) -> r 883 | ifoldl' = G.ifoldl' 884 | {-# INLINE ifoldl' #-} 885 | 886 | -- | /O(n)/ Right fold (function applied to each element and its index) 887 | ifoldr :: (G.Vector u a, G.Vector v b) => (Int -> (a, b) -> r -> r) -> r -> Vector u v (a, b) -> r 888 | ifoldr = G.ifoldr 889 | {-# INLINE ifoldr #-} 890 | 891 | -- | /O(n)/ Right fold with strict accumulator (function applied to each 892 | -- element and its index) 893 | ifoldr' :: (G.Vector u a, G.Vector v b) => (Int -> (a, b) -> r -> r) -> r -> Vector u v (a, b) -> r 894 | ifoldr' = G.ifoldr' 895 | {-# INLINE ifoldr' #-} 896 | 897 | -- Specialised folds 898 | -- ----------------- 899 | 900 | -- | /O(n)/ Check if all elements satisfy the predicate. 901 | all :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> Bool 902 | {-# INLINE all #-} 903 | all = G.all 904 | 905 | -- | /O(n)/ Check if any element satisfies the predicate. 906 | any :: (G.Vector u a, G.Vector v b) => ((a, b) -> Bool) -> Vector u v (a, b) -> Bool 907 | {-# INLINE any #-} 908 | any = G.any 909 | 910 | {- 911 | -- | /O(n)/ Compute the sum of the elements 912 | sum :: (G.Vector u a, G.Vector v b, Num a) => Vector u v (a, b) -> (a, b) 913 | {-# INLINE sum #-} 914 | sum = G.sum 915 | 916 | -- | /O(n)/ Compute the product of the elements 917 | product :: ((G.Vector u a, G.Vector v b), Num a) => Vector u v (a, b) -> (a, b) 918 | {-# INLINE product #-} 919 | product = G.product 920 | -} 921 | 922 | -- | /O(n)/ Yield the maximum element of the vector. The vector may not be 923 | -- empty. 924 | maximum :: (G.Vector u a, G.Vector v b, Ord a, Ord b) => Vector u v (a, b) -> (a, b) 925 | {-# INLINE maximum #-} 926 | maximum = G.maximum 927 | 928 | -- | /O(n)/ Yield the maximum element of the vector according to the given 929 | -- comparison function. The vector may not be empty. 930 | maximumBy :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> Ordering) -> Vector u v (a, b) -> (a, b) 931 | {-# INLINE maximumBy #-} 932 | maximumBy = G.maximumBy 933 | 934 | -- | /O(n)/ Yield the minimum element of the vector. The vector may not be 935 | -- empty. 936 | minimum :: (G.Vector u a, G.Vector v b, Ord a, Ord b) => Vector u v (a, b) -> (a, b) 937 | {-# INLINE minimum #-} 938 | minimum = G.minimum 939 | 940 | -- | /O(n)/ Yield the minimum element of the vector according to the given 941 | -- comparison function. The vector may not be empty. 942 | minimumBy :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> Ordering) -> Vector u v (a, b) -> (a, b) 943 | {-# INLINE minimumBy #-} 944 | minimumBy = G.minimumBy 945 | 946 | -- | /O(n)/ Yield the index of the maximum element of the vector. The vector 947 | -- may not be empty. 948 | maxIndex :: (G.Vector u a, G.Vector v b, Ord a, Ord b) => Vector u v (a, b) -> Int 949 | {-# INLINE maxIndex #-} 950 | maxIndex = G.maxIndex 951 | 952 | -- | /O(n)/ Yield the index of the maximum element of the vector according to 953 | -- the given comparison function. The vector may not be empty. 954 | maxIndexBy :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> Ordering) -> Vector u v (a, b) -> Int 955 | {-# INLINE maxIndexBy #-} 956 | maxIndexBy = G.maxIndexBy 957 | 958 | -- | /O(n)/ Yield the index of the minimum element of the vector. The vector 959 | -- may not be empty. 960 | minIndex :: (G.Vector u a, G.Vector v b, Ord a, Ord b) => Vector u v (a, b) -> Int 961 | {-# INLINE minIndex #-} 962 | minIndex = G.minIndex 963 | 964 | -- | /O(n)/ Yield the index of the minimum element of the vector according to 965 | -- the given comparison function. The vector may not be empty. 966 | minIndexBy :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> Ordering) -> Vector u v (a, b) -> Int 967 | {-# INLINE minIndexBy #-} 968 | minIndexBy = G.minIndexBy 969 | 970 | -- Monadic folds 971 | -- ------------- 972 | 973 | -- | /O(n)/ Monadic fold 974 | foldM :: (Monad m, G.Vector u a, G.Vector v b) => (r -> (a, b) -> m r) -> r -> Vector u v (a, b) -> m r 975 | foldM = G.foldM 976 | {-# INLINE foldM #-} 977 | 978 | -- | /O(n)/ Monadic fold over non-empty vectors 979 | fold1M :: (Monad m, G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> m (a, b)) -> Vector u v (a, b) -> m (a, b) 980 | {-# INLINE fold1M #-} 981 | fold1M = G.fold1M 982 | 983 | -- | /O(n)/ Monadic fold with strict accumulator 984 | foldM' :: (Monad m, G.Vector u a, G.Vector v b) => (r -> (a, b) -> m r) -> r -> Vector u v (a, b) -> m r 985 | {-# INLINE foldM' #-} 986 | foldM' = G.foldM' 987 | 988 | -- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator 989 | fold1M' :: (Monad m, G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> m (a, b)) -> Vector u v (a, b) -> m (a, b) 990 | {-# INLINE fold1M' #-} 991 | fold1M' = G.fold1M' 992 | 993 | -- | /O(n)/ Monadic fold that discards the result 994 | foldM_ :: (Monad m, G.Vector u a, G.Vector v b) => (r -> (a, b) -> m r) -> r -> Vector u v (a, b) -> m () 995 | {-# INLINE foldM_ #-} 996 | foldM_ = G.foldM_ 997 | 998 | -- | /O(n)/ Monadic fold over non-empty vectors that discards the result 999 | fold1M_ :: (Monad m, G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> m (a, b)) -> Vector u v (a, b) -> m () 1000 | {-# INLINE fold1M_ #-} 1001 | fold1M_ = G.fold1M_ 1002 | 1003 | -- | /O(n)/ Monadic fold with strict accumulator that discards the result 1004 | foldM'_ :: (Monad m, G.Vector u a, G.Vector v b) => (r -> (a, b) -> m r) -> r -> Vector u v (a, b) -> m () 1005 | {-# INLINE foldM'_ #-} 1006 | foldM'_ = G.foldM'_ 1007 | 1008 | -- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator 1009 | -- that discards the result 1010 | fold1M'_ :: (Monad m, G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> m (a, b)) -> Vector u v (a, b) -> m () 1011 | {-# INLINE fold1M'_ #-} 1012 | fold1M'_ = G.fold1M'_ 1013 | 1014 | 1015 | -- Prefix sums (scans) 1016 | -- ------------------- 1017 | 1018 | -- | /O(n)/ Prescan 1019 | -- 1020 | -- @ 1021 | -- prescanl f z = 'init' . 'scanl' f z 1022 | -- @ 1023 | -- 1024 | -- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@ 1025 | -- 1026 | prescanl :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (a, b)) -> (a, b) -> Vector u v (c, d) -> Vector u v (a, b) 1027 | prescanl = G.prescanl 1028 | {-# INLINE prescanl #-} 1029 | 1030 | -- | /O(n)/ Prescan with strict accumulator 1031 | prescanl' :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (a, b)) -> (a, b) -> Vector u v (c, d) -> Vector u v (a, b) 1032 | prescanl' = G.prescanl' 1033 | {-# INLINE prescanl' #-} 1034 | 1035 | -- | /O(n)/ Scan 1036 | -- 1037 | -- @ 1038 | -- postscanl f z = 'tail' . 'scanl' f z 1039 | -- @ 1040 | -- 1041 | -- Example: @postscanl (+) 0 \<1,2,3,4\> = \<1,3,6,10\>@ 1042 | -- 1043 | postscanl :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (a, b)) -> (a, b) -> Vector u v (c, d) -> Vector u v (a, b) 1044 | postscanl = G.postscanl 1045 | {-# INLINE postscanl #-} 1046 | 1047 | -- | /O(n)/ Scan with strict accumulator 1048 | postscanl' :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (a, b)) -> (a, b) -> Vector u v (c, d) -> Vector u v (a, b) 1049 | postscanl' = G.postscanl' 1050 | {-# INLINE postscanl' #-} 1051 | 1052 | -- | /O(n)/ Haskell-style scan 1053 | -- 1054 | -- > scanl f z = 1055 | -- > where y1 = z 1056 | -- > yi = f y(i-1) x(i-1) 1057 | -- 1058 | -- Example: @scanl (+) 0 \<1,2,3,4\> = \<0,1,3,6,10\>@ 1059 | -- 1060 | scanl :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (a, b)) -> (a, b) -> Vector u v (c, d) -> Vector u v (a, b) 1061 | scanl = G.scanl 1062 | {-# INLINE scanl #-} 1063 | 1064 | -- | /O(n)/ Haskell-style scan with strict accumulator 1065 | scanl' :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (a, b)) -> (a, b) -> Vector u v (c, d) -> Vector u v (a, b) 1066 | scanl' = G.scanl' 1067 | {-# INLINE scanl' #-} 1068 | 1069 | -- | /O(n)/ Scan over a non-empty vector 1070 | -- 1071 | -- > scanl f = 1072 | -- > where y1 = x1 1073 | -- > yi = f y(i-1) xi 1074 | -- 1075 | scanl1 :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> (a, b)) -> Vector u v (a, b) -> Vector u v (a, b) 1076 | scanl1 = G.scanl1 1077 | {-# INLINE scanl1 #-} 1078 | 1079 | -- | /O(n)/ Scan over a non-empty vector with a strict accumulator 1080 | scanl1' :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> (a, b)) -> Vector u v (a, b) -> Vector u v (a, b) 1081 | scanl1' = G.scanl1' 1082 | {-# INLINE scanl1' #-} 1083 | 1084 | -- | /O(n)/ Right-to-left prescan 1085 | -- 1086 | -- @ 1087 | -- prescanr f z = 'reverse' . 'prescanl' (flip f) z . 'reverse' 1088 | -- @ 1089 | -- 1090 | prescanr :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (c, d)) -> (c, d) -> Vector u v (a, b) -> Vector u v (c, d) 1091 | {-# INLINE prescanr #-} 1092 | prescanr = G.prescanr 1093 | 1094 | -- | /O(n)/ Right-to-left prescan with strict accumulator 1095 | prescanr' :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (c, d)) -> (c, d) -> Vector u v (a, b) -> Vector u v (c, d) 1096 | prescanr' = G.prescanr' 1097 | {-# INLINE prescanr' #-} 1098 | 1099 | -- | /O(n)/ Right-to-left scan 1100 | postscanr :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (c, d)) -> (c, d) -> Vector u v (a, b) -> Vector u v (c, d) 1101 | postscanr = G.postscanr 1102 | {-# INLINE postscanr #-} 1103 | 1104 | -- | /O(n)/ Right-to-left scan with strict accumulator 1105 | postscanr' :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (c, d)) -> (c, d) -> Vector u v (a, b) -> Vector u v (c, d) 1106 | postscanr' = G.postscanr' 1107 | {-# INLINE postscanr' #-} 1108 | 1109 | -- | /O(n)/ Right-to-left Haskell-style scan 1110 | scanr :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (c, d)) -> (c, d) -> Vector u v (a, b) -> Vector u v (c, d) 1111 | scanr = G.scanr 1112 | {-# INLINE scanr #-} 1113 | 1114 | -- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator 1115 | scanr' :: (G.Vector u a, G.Vector v b, G.Vector u c, G.Vector v d) => ((a, b) -> (c, d) -> (c, d)) -> (c, d) -> Vector u v (a, b) -> Vector u v (c, d) 1116 | scanr' = G.scanr' 1117 | {-# INLINE scanr' #-} 1118 | 1119 | -- | /O(n)/ Right-to-left scan over a non-empty vector 1120 | scanr1 :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> (a, b)) -> Vector u v (a, b) -> Vector u v (a, b) 1121 | {-# INLINE scanr1 #-} 1122 | scanr1 = G.scanr1 1123 | 1124 | -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict 1125 | -- accumulator 1126 | scanr1' :: (G.Vector u a, G.Vector v b) => ((a, b) -> (a, b) -> (a, b)) -> Vector u v (a, b) -> Vector u v (a, b) 1127 | {-# INLINE scanr1' #-} 1128 | scanr1' = G.scanr1' 1129 | 1130 | -- Conversions - Lists 1131 | -- ------------------------ 1132 | 1133 | projectFst :: Vector u v (a, b) -> u a 1134 | projectFst (V as _) = as 1135 | {-# INLINE projectFst #-} 1136 | 1137 | projectSnd :: Vector u v (a, b) -> v b 1138 | projectSnd (V _ bs) = bs 1139 | {-# INLINE projectSnd #-} 1140 | 1141 | -- | Warning: The vectors are assumed to have the same length. This is not checked! 1142 | unsafeZip :: u a -> v b -> Vector u v (a, b) 1143 | unsafeZip = V 1144 | {-# INLINE unsafeZip #-} 1145 | 1146 | -- | /O(n)/ Convert a vector to a list 1147 | toList :: (G.Vector u a, G.Vector v b) => Vector u v (a, b) -> [(a, b)] 1148 | toList = G.toList 1149 | {-# INLINE toList #-} 1150 | 1151 | -- | /O(n)/ Convert a list to a vector 1152 | fromList :: (G.Vector u a, G.Vector v b) => [(a, b)] -> Vector u v (a, b) 1153 | fromList = G.fromList 1154 | {-# INLINE fromList #-} 1155 | 1156 | -- | /O(n)/ Convert the first @n@ elements of a list to a vector 1157 | -- 1158 | -- @ 1159 | -- fromListN n xs = 'fromList' ('take' n xs) 1160 | -- @ 1161 | fromListN :: (G.Vector u a, G.Vector v b) => Int -> [(a, b)] -> Vector u v (a, b) 1162 | fromListN = G.fromListN 1163 | {-# INLINE fromListN #-} 1164 | 1165 | -- Conversions - Mutable vectors 1166 | -- ----------------------------- 1167 | 1168 | -- | /O(1)/ Unsafe convert a mutable vector to an immutable one without 1169 | -- copying. The mutable vector may not be used after this operation. 1170 | unsafeFreeze :: (G.Vector u a, G.Vector v b, PrimMonad m) => G.Mutable (Vector u v) (PrimState m) (a, b) -> m (Vector u v (a, b)) 1171 | unsafeFreeze = G.unsafeFreeze 1172 | {-# INLINE unsafeFreeze #-} 1173 | 1174 | -- | /O(1)/ Unsafely convert an immutable vector to a mutable one without 1175 | -- copying. The immutable vector may not be used after this operation. 1176 | unsafeThaw :: (G.Vector u a, G.Vector v b, PrimMonad m) => Vector u v (a, b) -> m (G.Mutable (Vector u v) (PrimState m) (a, b)) 1177 | unsafeThaw = G.unsafeThaw 1178 | {-# INLINE unsafeThaw #-} 1179 | 1180 | -- | /O(n)/ Yield a mutable copy of the immutable vector. 1181 | thaw :: (G.Vector u a, G.Vector v b, PrimMonad m) => Vector u v (a, b) -> m (G.Mutable (Vector u v) (PrimState m) (a, b)) 1182 | thaw = G.thaw 1183 | {-# INLINE thaw #-} 1184 | 1185 | -- | /O(n)/ Yield an immutable copy of the mutable vector. 1186 | freeze :: (G.Vector u a, G.Vector v b, PrimMonad m) => G.Mutable (Vector u v) (PrimState m) (a, b) -> m (Vector u v (a, b)) 1187 | freeze = G.freeze 1188 | {-# INLINE freeze #-} 1189 | 1190 | -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must 1191 | -- have the same length. This is not checked. 1192 | unsafeCopy 1193 | :: (G.Vector u a, G.Vector v b, PrimMonad m) => G.Mutable (Vector u v) (PrimState m) (a, b) -> Vector u v (a, b) -> m () 1194 | unsafeCopy = G.unsafeCopy 1195 | {-# INLINE unsafeCopy #-} 1196 | 1197 | -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must 1198 | -- have the same length. 1199 | copy :: (G.Vector u a, G.Vector v b, PrimMonad m) => G.Mutable (Vector u v) (PrimState m) (a, b) -> Vector u v (a, b) -> m () 1200 | copy = G.copy 1201 | {-# INLINE copy #-} 1202 | -------------------------------------------------------------------------------- /src/Data/Vector/Mixed.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE FlexibleInstances #-} 3 | {-# LANGUAGE FlexibleContexts #-} 4 | {-# LANGUAGE MultiParamTypeClasses #-} 5 | {-# LANGUAGE TypeFamilies #-} 6 | {-# LANGUAGE Rank2Types #-} 7 | {-# LANGUAGE BangPatterns #-} 8 | ----------------------------------------------------------------------------- 9 | -- | 10 | -- Copyright : (C) 2013 Edward Kmett, 11 | -- License : BSD-style (see the file LICENSE) 12 | -- 13 | -- Maintainer : Edward Kmett 14 | -- Stability : experimental 15 | -- Portability : non-portable 16 | -- 17 | -- A mixed 'Vector' lets you make a 'Vector' out of any other vector type 18 | -- you have lying around, and all of the combinators are defined to allow 19 | -- you to freely mix input vector type wherever possible. 20 | -- 21 | -- This enables you to work with a mixture of boxed and unboxed data. 22 | ----------------------------------------------------------------------------- 23 | module Data.Vector.Mixed 24 | ( 25 | -- * Mixed vectors 26 | Vector, MVector, Mixed(..) 27 | 28 | -- * Accessors 29 | 30 | -- ** Length information 31 | , length 32 | , null 33 | 34 | -- ** Indexing 35 | , (!), (!?), head, last 36 | , unsafeIndex, unsafeHead, unsafeLast 37 | 38 | -- ** Monadic indexing 39 | , indexM, headM, lastM 40 | , unsafeIndexM, unsafeHeadM, unsafeLastM 41 | 42 | -- ** Extracting subvectors (slicing) 43 | , slice, init, tail, take, drop, splitAt 44 | , unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop 45 | 46 | -- * Construction 47 | 48 | -- ** Initialisation 49 | , empty, singleton, replicate, generate, iterateN 50 | 51 | -- ** Monadic initialisation 52 | , replicateM, generateM, create 53 | 54 | -- ** Unfolding 55 | , unfoldr, unfoldrN 56 | , constructN, constructrN 57 | 58 | -- ** Enumeration 59 | , enumFromN, enumFromStepN, enumFromTo, enumFromThenTo 60 | 61 | -- ** Concatenation 62 | , cons, snoc, (++), concat 63 | 64 | -- ** Restricting memory usage 65 | , force 66 | 67 | -- * Modifying vectors 68 | 69 | -- ** Bulk updates 70 | , (//), update, update_ 71 | , unsafeUpd, unsafeUpdate, unsafeUpdate_ 72 | 73 | -- ** Accumulations 74 | , accum, accumulate, accumulate_ 75 | , unsafeAccum, unsafeAccumulate, unsafeAccumulate_ 76 | 77 | -- ** Permutations 78 | , reverse, backpermute, unsafeBackpermute 79 | 80 | -- ** Safe destructive updates 81 | , modify 82 | 83 | -- * Elementwise operations 84 | 85 | -- ** Indexing 86 | , indexed 87 | 88 | -- ** Mapping 89 | , map, imap, concatMap 90 | 91 | -- ** Monadic mapping 92 | , mapM, mapM_, forM, forM_ 93 | 94 | -- ** Zipping 95 | , zipWith, zipWith3, zipWith4, zipWith5, zipWith6 96 | , izipWith, izipWith3, izipWith4, izipWith5, izipWith6 97 | , zip, zip3, zip4, zip5, zip6 98 | 99 | -- ** Monadic zipping 100 | , zipWithM, zipWithM_ 101 | 102 | -- ** Unzipping 103 | , unzip, unzip3, unzip4, unzip5, unzip6 104 | 105 | -- * Working with predicates 106 | 107 | -- ** Filtering 108 | , filter, ifilter, filterM 109 | , takeWhile, dropWhile 110 | 111 | -- ** Partitioning 112 | , partition, unstablePartition, span, break 113 | 114 | -- ** Searching 115 | , elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices 116 | 117 | -- * Folding 118 | , foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1' 119 | , ifoldl, ifoldl', ifoldr, ifoldr' 120 | 121 | -- ** Specialised folds 122 | , all, any, and, or 123 | , sum, product 124 | , maximum, maximumBy, minimum, minimumBy 125 | , minIndex, minIndexBy, maxIndex, maxIndexBy 126 | 127 | -- ** Monadic folds 128 | , foldM, foldM', fold1M, fold1M' 129 | , foldM_, foldM'_, fold1M_, fold1M'_ 130 | 131 | -- ** Monadic sequencing 132 | , sequence, sequence_ 133 | 134 | -- * Prefix sums (scans) 135 | , prescanl, prescanl' 136 | , postscanl, postscanl' 137 | , scanl, scanl', scanl1, scanl1' 138 | , prescanr, prescanr' 139 | , postscanr, postscanr' 140 | , scanr, scanr', scanr1, scanr1' 141 | 142 | -- * Conversions 143 | 144 | -- ** Lists 145 | , toList, fromList, fromListN 146 | 147 | -- ** Other vector types 148 | , G.convert 149 | 150 | -- ** Mutable vectors 151 | , freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy 152 | ) where 153 | 154 | 155 | -- import qualified Data.Vector.Hybrid.Internal as H 156 | import qualified Data.Vector.Generic as G 157 | import qualified Data.Vector.Generic.Mutable as GM 158 | import qualified Data.Vector.Generic.New as New 159 | import Data.Vector.Mixed.Internal 160 | import Data.Vector.Internal.Check as Ck 161 | import qualified Data.Vector.Fusion.Stream as Stream 162 | import Data.Vector.Fusion.Stream (MStream, Stream) 163 | import qualified Data.Vector.Fusion.Stream.Monadic as MStream 164 | 165 | -- import Control.DeepSeq ( NFData, rnf ) 166 | import Control.Monad ( liftM ) 167 | import Control.Monad.ST ( ST ) 168 | import Control.Monad.Primitive 169 | 170 | import Prelude hiding ( length, null, 171 | replicate, (++), concat, 172 | head, last, 173 | init, tail, take, drop, splitAt, reverse, 174 | map, concatMap, 175 | zipWith, zipWith3, zip, zip3, unzip, unzip3, 176 | filter, takeWhile, dropWhile, span, break, 177 | elem, notElem, 178 | foldl, foldl1, foldr, foldr1, 179 | all, any, and, or, sum, product, minimum, maximum, 180 | scanl, scanl1, scanr, scanr1, 181 | enumFromTo, enumFromThenTo, 182 | mapM, mapM_, sequence, sequence_ ) 183 | 184 | #define BOUNDS_CHECK(f) (Ck.f __FILE__ __LINE__ Ck.Bounds) 185 | #define UNSAFE_CHECK(f) (Ck.f __FILE__ __LINE__ Ck.Unsafe) 186 | 187 | -- import Data.Typeable ( Typeable ) 188 | -- import Data.Data ( Data(..) ) 189 | -- import Text.Read ( Read(..), readListPrecDefault ) 190 | 191 | -- import Data.Monoid ( Monoid(..) ) 192 | -- import qualified Control.Applicative as Applicative 193 | -- import qualified Data.Foldable as Foldable 194 | -- import qualified Data.Traversable as Traversable 195 | 196 | -- Length information 197 | -- ------------------ 198 | 199 | -- | /O(1)/ Yield the length of the vector. 200 | length :: G.Vector v a => v a -> Int 201 | length = G.length 202 | {-# INLINE length #-} 203 | 204 | -- | /O(1)/ Test whether a vector if empty 205 | null :: G.Vector v a => v a -> Bool 206 | null = G.null 207 | {-# INLINE null #-} 208 | 209 | -- Indexing 210 | -- -------- 211 | 212 | -- | O(1) Indexing 213 | (!) :: G.Vector v a => v a -> Int -> a 214 | (!) = (G.!) 215 | {-# INLINE (!) #-} 216 | 217 | -- | O(1) Safe indexing 218 | (!?) :: G.Vector v a => v a -> Int -> Maybe a 219 | (!?) = (G.!?) 220 | {-# INLINE (!?) #-} 221 | 222 | -- | /O(1)/ First element 223 | head :: G.Vector v a => v a -> a 224 | head = G.head 225 | {-# INLINE head #-} 226 | 227 | -- | /O(1)/ Last element 228 | last :: G.Vector v a => v a -> a 229 | last = G.last 230 | {-# INLINE last #-} 231 | 232 | -- | /O(1)/ Unsafe indexing without bounds checking 233 | unsafeIndex :: G.Vector v a => v a -> Int -> a 234 | unsafeIndex = G.unsafeIndex 235 | {-# INLINE unsafeIndex #-} 236 | 237 | -- | /O(1)/ First element without checking if the vector is empty 238 | unsafeHead :: G.Vector v a => v a -> a 239 | unsafeHead = G.unsafeHead 240 | {-# INLINE unsafeHead #-} 241 | 242 | -- | /O(1)/ Last element without checking if the vector is empty 243 | unsafeLast :: G.Vector v a => v a -> a 244 | unsafeLast = G.unsafeLast 245 | {-# INLINE unsafeLast #-} 246 | 247 | -- Monadic indexing 248 | -- ---------------- 249 | 250 | -- | /O(1)/ Indexing in a monad. 251 | -- 252 | -- The monad allows operations to be strict in the vector when necessary. 253 | -- Suppose vector copying is implemented like this: 254 | -- 255 | -- > copy mv v = ... write mv i (v ! i) ... 256 | -- 257 | -- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@ 258 | -- would unnecessarily retain a reference to @v@ in each element written. 259 | -- 260 | -- With 'indexM', copying can be implemented like this instead: 261 | -- 262 | -- > copy mv v = ... do 263 | -- > x <- indexM v i 264 | -- > write mv i x 265 | -- 266 | -- Here, no references to @v@ are retained because indexing (but /not/ the 267 | -- elements) is evaluated eagerly. 268 | -- 269 | indexM :: (Monad m, G.Vector v a) => v a -> Int -> m a 270 | indexM = G.indexM 271 | {-# INLINE indexM #-} 272 | 273 | -- | /O(1)/ First element of a vector in a monad. See 'indexM' for an 274 | -- explanation of why this is useful. 275 | headM :: (Monad m, G.Vector v a) => v a -> m a 276 | headM = G.headM 277 | {-# INLINE headM #-} 278 | 279 | -- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an 280 | -- explanation of why this is useful. 281 | lastM :: (Monad m, G.Vector v a) => v a -> m a 282 | lastM = G.lastM 283 | {-# INLINE lastM #-} 284 | 285 | -- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an 286 | -- explanation of why this is useful. 287 | unsafeIndexM :: (Monad m, G.Vector v a) => v a -> Int -> m a 288 | unsafeIndexM = G.unsafeIndexM 289 | {-# INLINE unsafeIndexM #-} 290 | 291 | -- | /O(1)/ First element in a monad without checking for empty vectors. 292 | -- See 'indexM' for an explanation of why this is useful. 293 | unsafeHeadM :: (Monad m, G.Vector v a) => v a -> m a 294 | unsafeHeadM = G.unsafeHeadM 295 | {-# INLINE unsafeHeadM #-} 296 | 297 | -- | /O(1)/ Last element in a monad without checking for empty vectors. 298 | -- See 'indexM' for an explanation of why this is useful. 299 | unsafeLastM :: (Monad m, G.Vector v a) => v a -> m a 300 | unsafeLastM = G.unsafeLastM 301 | {-# INLINE unsafeLastM #-} 302 | 303 | -- Extracting subvectors (slicing) 304 | -- ------------------------------- 305 | 306 | -- | /O(1)/ Yield a slice of the vector without copying it. The vector must 307 | -- contain at least @i+n@ elements. 308 | slice :: Mixed u v a => Int -- ^ @i@ starting index 309 | -> Int -- ^ @n@ length 310 | -> v a 311 | -> Vector a 312 | slice i j m = mix (G.slice i j m) 313 | {-# INLINE slice #-} 314 | 315 | -- | /O(1)/ Yield all but the last element without copying. The vector may not 316 | -- be empty. 317 | init :: Mixed u v a => v a -> Vector a 318 | init m = mix (G.init m) 319 | {-# INLINE init #-} 320 | 321 | -- | /O(1)/ Yield all but the first element without copying. The vector may not 322 | -- be empty. 323 | tail :: Mixed u v a => v a -> Vector a 324 | tail m = mix (G.tail m) 325 | {-# INLINE tail #-} 326 | 327 | -- | /O(1)/ Yield at the first @n@ elements without copying. The vector may 328 | -- contain less than @n@ elements in which case it is returned unchanged. 329 | take :: Mixed u v a => Int -> v a -> Vector a 330 | take i m = mix (G.take i m) 331 | {-# INLINE take #-} 332 | 333 | -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may 334 | -- contain less than @n@ elements in which case an empty vector is returned. 335 | drop :: Mixed u v a => Int -> v a -> Vector a 336 | drop i m = mix (G.drop i m) 337 | {-# INLINE drop #-} 338 | 339 | -- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying. 340 | -- 341 | -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ 342 | -- but slightly more efficient. 343 | splitAt :: Mixed u v a => Int -> v a -> (Vector a, Vector a) 344 | splitAt i m = case G.splitAt i m of 345 | (xs, ys) -> (mix xs, mix ys) 346 | {-# INLINE splitAt #-} 347 | 348 | -- | /O(1)/ Yield a slice of the vector without copying. The vector must 349 | -- contain at least @i+n@ elements but this is not checked. 350 | unsafeSlice :: Mixed u v a => Int -- ^ @i@ starting index 351 | -> Int -- ^ @n@ length 352 | -> v a 353 | -> Vector a 354 | unsafeSlice i j m = mix (G.unsafeSlice i j m) 355 | {-# INLINE unsafeSlice #-} 356 | 357 | -- | /O(1)/ Yield all but the last element without copying. The vector may not 358 | -- be empty but this is not checked. 359 | unsafeInit :: Mixed u v a => v a -> Vector a 360 | unsafeInit m = mix (G.unsafeInit m) 361 | {-# INLINE unsafeInit #-} 362 | 363 | -- | /O(1)/ Yield all but the first element without copying. The vector may not 364 | -- be empty but this is not checked. 365 | unsafeTail :: Mixed u v a => v a -> Vector a 366 | unsafeTail m = mix (G.unsafeTail m) 367 | {-# INLINE unsafeTail #-} 368 | 369 | -- | /O(1)/ Yield the first @n@ elements without copying. The vector must 370 | -- contain at least @n@ elements but this is not checked. 371 | unsafeTake :: Mixed u v a => Int -> v a -> Vector a 372 | unsafeTake i m = mix (G.unsafeTake i m) 373 | {-# INLINE unsafeTake #-} 374 | 375 | -- | /O(1)/ Yield all but the first @n@ elements without copying. The vector 376 | -- must contain at least @n@ elements but this is not checked. 377 | unsafeDrop :: Mixed u v a => Int -> v a -> Vector a 378 | unsafeDrop i m = mix (G.unsafeDrop i m) 379 | {-# INLINE unsafeDrop #-} 380 | 381 | -- Initialisation 382 | -- -------------- 383 | 384 | -- | /O(1)/ Empty vector 385 | empty :: Vector a 386 | empty = G.empty 387 | {-# INLINE empty #-} 388 | 389 | -- | /O(1)/ Vector with exactly one element 390 | singleton :: a -> Vector a 391 | singleton = G.singleton 392 | {-# INLINE singleton #-} 393 | 394 | -- | /O(n)/ Vector of the given length with the same value in each position 395 | replicate :: Int -> a -> Vector a 396 | replicate = G.replicate 397 | {-# INLINE replicate #-} 398 | 399 | -- | /O(n)/ Construct a vector of the given length by applying the function to 400 | -- each index 401 | generate :: Int -> (Int -> a) -> Vector a 402 | generate = G.generate 403 | {-# INLINE generate #-} 404 | 405 | -- | /O(n)/ Apply function n times to value. Zeroth element is original value. 406 | iterateN :: Int -> (a -> a) -> a -> Vector a 407 | iterateN = G.iterateN 408 | {-# INLINE iterateN #-} 409 | 410 | -- Unfolding 411 | -- --------- 412 | 413 | -- | /O(n)/ Construct a vector by repeatedly applying the generator function 414 | -- to a seed. The generator function yields 'Just' the next element and the 415 | -- new seed or 'Nothing' if there are no more elements. 416 | -- 417 | -- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10 418 | -- > = <10,9,8,7,6,5,4,3,2,1> 419 | unfoldr :: (b -> Maybe (a, b)) -> b -> Vector a 420 | unfoldr = G.unfoldr 421 | {-# INLINE unfoldr #-} 422 | 423 | -- | /O(n)/ Construct a vector with at most @n@ by repeatedly applying the 424 | -- generator function to the a seed. The generator function yields 'Just' the 425 | -- next element and the new seed or 'Nothing' if there are no more elements. 426 | -- 427 | -- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8> 428 | unfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Vector a 429 | unfoldrN = G.unfoldrN 430 | {-# INLINE unfoldrN #-} 431 | 432 | -- | /O(n)/ Construct a vector with @n@ elements by repeatedly applying the 433 | -- generator function to the already constructed part of the vector. 434 | -- 435 | -- > constructN 3 f = let a = f <> ; b = f ; c = f in f 436 | -- 437 | constructN :: Int -> (Vector a -> a) -> Vector a 438 | constructN = G.constructN 439 | {-# INLINE constructN #-} 440 | 441 | -- | /O(n)/ Construct a vector with @n@ elements from right to left by 442 | -- repeatedly applying the generator function to the already constructed part 443 | -- of the vector. 444 | -- 445 | -- > constructrN 3 f = let a = f <> ; b = f ; c = f in f 446 | -- 447 | constructrN :: Int -> (Vector a -> a) -> Vector a 448 | constructrN = G.constructrN 449 | {-# INLINE constructrN #-} 450 | 451 | -- Enumeration 452 | -- ----------- 453 | 454 | -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+1@ 455 | -- etc. This operation is usually more efficient than 'enumFromTo'. 456 | -- 457 | -- > enumFromN 5 3 = <5,6,7> 458 | enumFromN :: Num a => a -> Int -> Vector a 459 | enumFromN = G.enumFromN 460 | {-# INLINE enumFromN #-} 461 | 462 | -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@, 463 | -- @x+y+y@ etc. This operations is usually more efficient than 'enumFromThenTo'. 464 | -- 465 | -- > enumFromStepN 1 0.1 5 = <1,1.1,1.2,1.3,1.4> 466 | enumFromStepN :: Num a => a -> a -> Int -> Vector a 467 | enumFromStepN = G.enumFromStepN 468 | {-# INLINE enumFromStepN #-} 469 | 470 | -- | /O(n)/ Enumerate values from @x@ to @y@. 471 | -- 472 | -- /WARNING:/ This operation can be very inefficient. If at all possible, use 473 | -- 'enumFromN' instead. 474 | enumFromTo :: Enum a => a -> a -> Vector a 475 | enumFromTo = G.enumFromTo 476 | {-# INLINE enumFromTo #-} 477 | 478 | -- | /O(n)/ Enumerate values from @x@ to @y@ with a specific step @z@. 479 | -- 480 | -- /WARNING:/ This operation can be very inefficient. If at all possible, use 481 | -- 'enumFromStepN' instead. 482 | enumFromThenTo :: Enum a => a -> a -> a -> Vector a 483 | enumFromThenTo = G.enumFromThenTo 484 | {-# INLINE enumFromThenTo #-} 485 | 486 | -- Concatenation 487 | -- ------------- 488 | 489 | -- | /O(n)/ Prepend an element 490 | cons :: Mixed u v a => a -> v a -> Vector a 491 | cons a as = mix (G.cons a as) 492 | {-# INLINE cons #-} 493 | 494 | -- | /O(n)/ Append an element 495 | snoc :: Mixed u v a => v a -> a -> Vector a 496 | snoc as a = mix (G.snoc as a) 497 | {-# INLINE snoc #-} 498 | 499 | infixr 5 ++ 500 | -- | /O(m+n)/ Concatenate two vectors 501 | (++) :: (Mixed u v a, Mixed u' v' a) => v a -> v' a -> Vector a 502 | m ++ n = mix m G.++ mix n 503 | {-# INLINE (++) #-} 504 | 505 | -- | /O(n)/ Concatenate all vectors in the list 506 | concat :: Mixed u v a => [v a] -> Vector a 507 | concat xs = mix (G.concat xs) 508 | {-# INLINE concat #-} 509 | 510 | -- Monadic initialisation 511 | -- ---------------------- 512 | 513 | -- | /O(n)/ Execute the monadic action the given number of times and store the 514 | -- results in a vector. 515 | replicateM :: Monad m => Int -> m a -> m (Vector a) 516 | replicateM = G.replicateM 517 | {-# INLINE replicateM #-} 518 | 519 | -- | /O(n)/ Construct a vector of the given length by applying the monadic 520 | -- action to each index 521 | generateM :: Monad m => Int -> (Int -> m a) -> m (Vector a) 522 | generateM = G.generateM 523 | {-# INLINE generateM #-} 524 | 525 | -- | Execute the monadic action and freeze the resulting vector. 526 | -- 527 | -- @ 528 | -- create (do { v \<- new 2; write v 0 \'a\'; write v 1 \'b\'; return v }) = \<'a','b'\> 529 | -- @ 530 | create :: Mixed u v a => (forall s. ST s (u s a)) -> Vector a 531 | -- NOTE: eta-expanded due to http://hackage.haskell.org/trac/ghc/ticket/4120 532 | create p = mix (G.create p) 533 | {-# INLINE create #-} 534 | 535 | -- Restricting memory usage 536 | -- ------------------------ 537 | 538 | -- | /O(n)/ Yield the argument but force it not to retain any extra memory, 539 | -- possibly by copying it. 540 | -- 541 | -- This is especially useful when dealing with slices. For example: 542 | -- 543 | -- > force (slice 0 2 ) 544 | -- 545 | -- Here, the slice retains a reference to the huge vector. Forcing it creates 546 | -- a copy of just the elements that belong to the slice and allows the huge 547 | -- vector to be garbage collected. 548 | force :: Mixed u v a => v a -> Vector a 549 | force m = mix (G.force m) 550 | {-# INLINE force #-} 551 | 552 | -- Bulk updates 553 | -- ------------ 554 | 555 | -- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector 556 | -- element at position @i@ by @a@. 557 | -- 558 | -- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7> 559 | -- 560 | (//) :: Mixed u v a => v a -- ^ initial vector (of length @m@) 561 | -> [(Int, a)] -- ^ list of index/value pairs (of length @n@) 562 | -> Vector a 563 | m // xs = mix (m G.// xs) 564 | {-# INLINE (//) #-} 565 | 566 | update_stream :: G.Vector v a => v a -> Stream (Int,a) -> v a 567 | update_stream = modifyWithStream GM.update 568 | {-# INLINE update_stream #-} 569 | 570 | -- | /O(m+n)/ For each pair @(i,a)@ from the vector of index/value pairs, 571 | -- replace the vector element at position @i@ by @a@. 572 | -- 573 | -- > update <5,9,2,7> <(2,1),(0,3),(2,8)> = <3,9,8,7> 574 | -- 575 | update :: (Mixed u v a, G.Vector v' (Int, a)) => v a -- ^ initial vector (of length @m@) 576 | -> v' (Int, a) -- ^ vector of index/value pairs (of length @n@) 577 | -> Vector a 578 | update v w = mix (update_stream v (G.stream w)) 579 | {-# INLINE update #-} 580 | 581 | -- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the 582 | -- corresponding value @a@ from the value vector, replace the element of the 583 | -- initial vector at position @i@ by @a@. 584 | -- 585 | -- > update_ <5,9,2,7> <2,0,2> <1,3,8> = <3,9,8,7> 586 | -- 587 | -- The function 'update' provides the same functionality and is usually more 588 | -- convenient. 589 | -- 590 | -- @ 591 | -- update_ xs is ys = 'update' xs ('zip' is ys) 592 | -- @ 593 | update_ :: 594 | ( Mixed u v a, G.Vector v' Int, G.Vector v'' a 595 | ) => v a -- ^ initial vector (of length @m@) 596 | -> v' Int -- ^ index vector (of length @n1@) 597 | -> v'' a -- ^ value vector (of length @n2@) 598 | -> Vector a 599 | update_ v is w = mix (update_stream v (Stream.zipWith (,) (G.stream is) (G.stream w))) 600 | {-# INLINE update_ #-} 601 | 602 | -- | Same as ('//') but without bounds checking. 603 | unsafeUpd :: Mixed u v a => v a -> [(Int, a)] -> Vector a 604 | unsafeUpd v us = mix (unsafeUpdate_stream v (Stream.fromList us)) 605 | {-# INLINE unsafeUpd #-} 606 | 607 | unsafeUpdate_stream :: G.Vector v a => v a -> Stream (Int,a) -> v a 608 | unsafeUpdate_stream = modifyWithStream GM.unsafeUpdate 609 | {-# INLINE unsafeUpdate_stream #-} 610 | 611 | -- | Same as 'update' but without bounds checking. 612 | unsafeUpdate :: (Mixed u v a, G.Vector v' (Int, a)) => v a -> v' (Int, a) -> Vector a 613 | unsafeUpdate v w = mix (unsafeUpdate_stream v (G.stream w)) 614 | {-# INLINE unsafeUpdate #-} 615 | 616 | -- | Same as 'update_' but without bounds checking. 617 | unsafeUpdate_ :: ( Mixed u v a, G.Vector v' Int, G.Vector v'' a 618 | ) => v a -> v' Int -> v'' a -> Vector a 619 | unsafeUpdate_ v is w = mix (unsafeUpdate_stream v (Stream.zipWith (,) (G.stream is) (G.stream w))) 620 | {-# INLINE unsafeUpdate_ #-} 621 | 622 | -- Accumulations 623 | -- ------------- 624 | 625 | -- | /O(m+n)/ For each pair @(i,b)@ from the list, replace the vector element 626 | -- @a@ at position @i@ by @f a b@. 627 | -- 628 | -- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4> 629 | accum :: Mixed u v a => (a -> b -> a) -- ^ accumulating function @f@ 630 | -> v a -- ^ initial vector (of length @m@) 631 | -> [(Int,b)] -- ^ list of index/value pairs (of length @n@) 632 | -> Vector a 633 | accum f v us = mix (accum_stream f v (Stream.fromList us)) 634 | {-# INLINE accum #-} 635 | 636 | -- | /O(m+n)/ For each pair @(i,b)@ from the vector of pairs, replace the vector 637 | -- element @a@ at position @i@ by @f a b@. 638 | -- 639 | -- > accumulate (+) <5,9,2> <(2,4),(1,6),(0,3),(1,7)> = <5+3, 9+6+7, 2+4> 640 | accumulate :: (Mixed u v a, G.Vector v' (Int, b)) 641 | => (a -> b -> a) -- ^ accumulating function @f@ 642 | -> v a -- ^ initial vector (of length @m@) 643 | -> v' (Int,b) -- ^ vector of index/value pairs (of length @n@) 644 | -> Vector a 645 | accumulate f v us = mix (accum_stream f v (G.stream us)) 646 | {-# INLINE accumulate #-} 647 | 648 | -- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the 649 | -- corresponding value @b@ from the the value vector, 650 | -- replace the element of the initial vector at 651 | -- position @i@ by @f a b@. 652 | -- 653 | -- > accumulate_ (+) <5,9,2> <2,1,0,1> <4,6,3,7> = <5+3, 9+6+7, 2+4> 654 | -- 655 | -- The function 'accumulate' provides the same functionality and is usually more 656 | -- convenient. 657 | -- 658 | -- @ 659 | -- accumulate_ f as is bs = 'accumulate' f as ('zip' is bs) 660 | -- @ 661 | accumulate_ 662 | :: (Mixed u v a, G.Vector v' Int, G.Vector v'' b) 663 | => (a -> b -> a) -- ^ accumulating function @f@ 664 | -> v a -- ^ initial vector (of length @m@) 665 | -> v' Int -- ^ index vector (of length @n1@) 666 | -> v'' b -- ^ value vector (of length @n2@) 667 | -> Vector a 668 | accumulate_ f v is xs = mix (accum_stream f v (Stream.zipWith (,) (G.stream is) (G.stream xs))) 669 | {-# INLINE accumulate_ #-} 670 | 671 | accum_stream :: G.Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a 672 | accum_stream f = modifyWithStream (GM.accum f) 673 | {-# INLINE accum_stream #-} 674 | 675 | -- | Same as 'accum' but without bounds checking. 676 | unsafeAccum :: Mixed u v a => (a -> b -> a) -> v a -> [(Int,b)] -> Vector a 677 | unsafeAccum f v us = mix (unsafeAccum_stream f v (Stream.fromList us)) 678 | 679 | {-# INLINE unsafeAccum #-} 680 | 681 | -- | Same as 'accumulate' but without bounds checking. 682 | unsafeAccumulate :: (Mixed u v a, G.Vector v' (Int, b)) => (a -> b -> a) -> v a -> v' (Int,b) -> Vector a 683 | unsafeAccumulate f v us = mix (unsafeAccum_stream f v (G.stream us)) 684 | {-# INLINE unsafeAccumulate #-} 685 | 686 | -- | Same as 'accumulate_' but without bounds checking. 687 | unsafeAccumulate_ 688 | :: (Mixed u v a, G.Vector v' Int, G.Vector v'' b) 689 | => (a -> b -> a) -> v a -> v' Int -> v'' b -> Vector a 690 | unsafeAccumulate_ f v is xs = mix (unsafeAccum_stream f v (Stream.zipWith (,) (G.stream is) (G.stream xs))) 691 | {-# INLINE unsafeAccumulate_ #-} 692 | 693 | unsafeAccum_stream :: G.Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a 694 | unsafeAccum_stream f = modifyWithStream (GM.unsafeAccum f) 695 | {-# INLINE unsafeAccum_stream #-} 696 | 697 | -- Permutations 698 | -- ------------ 699 | 700 | -- | /O(n)/ Reverse a vector 701 | reverse :: Mixed u v a => v a -> Vector a 702 | reverse m = mix (G.reverse m) 703 | {-# INLINE reverse #-} 704 | 705 | -- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the 706 | -- index vector by @xs'!'i@. This is equivalent to @'map' (xs'!') is@ but is 707 | -- often much more efficient. 708 | -- 709 | -- > backpermute <0,3,2,3,1,0> = 710 | backpermute :: (Mixed u v a, G.Vector v' Int) => v a -> v' Int -> Vector a 711 | -- backpermute m n = G.backpermute (mix m) (mix n) 712 | -- {-# INLINE backpermute #-} 713 | 714 | -- This somewhat non-intuitive definition ensures that the resulting vector 715 | -- does not retain references to the original one even if it is lazy in its 716 | -- elements. This would not be the case if we simply used map (v!) 717 | backpermute v is = mix 718 | $ (`asTypeOf` v) 719 | $ seq v 720 | $ seq n 721 | $ G.unstream 722 | $ Stream.unbox 723 | $ Stream.map index 724 | $ G.stream is 725 | where 726 | n = length v 727 | 728 | {-# INLINE index #-} 729 | -- NOTE: we do it this way to avoid triggering LiberateCase on n in 730 | -- polymorphic code 731 | index i = BOUNDS_CHECK(checkIndex) "backpermute" i n 732 | $ G.basicUnsafeIndexM v i 733 | 734 | -- | Same as 'backpermute' but without bounds checking. 735 | unsafeBackpermute :: (Mixed u v a, G.Vector v' Int) => v a -> v' Int -> Vector a 736 | unsafeBackpermute v is = mix 737 | $ (`asTypeOf` v) 738 | $ seq v 739 | $ seq n 740 | $ G.unstream 741 | $ Stream.unbox 742 | $ Stream.map index 743 | $ G.stream is 744 | where 745 | n = length v 746 | 747 | {-# INLINE index #-} 748 | -- NOTE: we do it this way to avoid triggering LiberateCase on n in 749 | -- polymorphic code 750 | index i = UNSAFE_CHECK(checkIndex) "unsafeBackpermute" i n 751 | $ G.basicUnsafeIndexM v i 752 | 753 | {-# INLINE unsafeBackpermute #-} 754 | 755 | -- Safe destructive updates 756 | -- ------------------------ 757 | 758 | -- | Apply a destructive operation to a vector. The operation will be 759 | -- performed in place if it is safe to do so and will modify a copy of the 760 | -- vector otherwise. 761 | -- 762 | -- @ 763 | -- modify (\\v -> write v 0 \'x\') ('replicate' 3 \'a\') = \<\'x\',\'a\',\'a\'\> 764 | -- @ 765 | modify :: Mixed u v a => (forall s. u s a -> ST s ()) -> v a -> Vector a 766 | modify p v = mix (G.modify p v) 767 | {-# INLINE modify #-} 768 | 769 | -- Indexing 770 | -- -------- 771 | 772 | -- | /O(n)/ Pair each element in a vector with its index 773 | indexed :: (G.Vector v a, Mixed u v (Int, a)) => v a -> Vector (Int,a) 774 | indexed m = mix (G.indexed m) 775 | {-# INLINE indexed #-} 776 | 777 | -- Mapping 778 | -- ------- 779 | 780 | -- | /O(n)/ Map a function over a vector 781 | map :: G.Vector v a => (a -> b) -> v a -> Vector b 782 | map f = boxed . G.unstream . Stream.inplace (MStream.map f) . G.stream 783 | 784 | 785 | {-# INLINE map #-} 786 | 787 | -- | /O(n)/ Apply a function to every element of a vector and its index 788 | imap :: G.Vector v a => (Int -> a -> b) -> v a -> Vector b 789 | -- imap f m = mix (G.imap f m) 790 | imap f = boxed . G.unstream . Stream.inplace (MStream.map (uncurry f) . MStream.indexed) . G.stream 791 | {-# INLINE imap #-} 792 | 793 | -- | Map a function over a vector and concatenate the results. 794 | concatMap :: (Mixed u v b, G.Vector v' a) => (a -> v b) -> v' a -> Vector b 795 | concatMap f = mix . G.concat . Stream.toList . Stream.map f . G.stream 796 | {-# INLINE concatMap #-} 797 | 798 | -- Monadic mapping 799 | -- --------------- 800 | 801 | -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a 802 | -- vector of results 803 | mapM :: (Monad m, G.Vector v a) => (a -> m b) -> v a -> m (Vector b) 804 | mapM f = unstreamM . Stream.mapM f . G.stream 805 | {-# INLINE mapM #-} 806 | 807 | -- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the 808 | -- results 809 | mapM_ :: (Monad m, G.Vector v a) => (a -> m b) -> v a -> m () 810 | mapM_ f = Stream.mapM_ f . G.stream 811 | {-# INLINE mapM_ #-} 812 | 813 | -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a 814 | -- vector of results. Equvalent to @flip 'mapM'@. 815 | forM :: (Monad m, G.Vector v a) => v a -> (a -> m b) -> m (Vector b) 816 | forM as f = mapM f as 817 | {-# INLINE forM #-} 818 | 819 | -- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the 820 | -- results. Equivalent to @flip 'mapM_'@. 821 | forM_ :: (Monad m, G.Vector v a) => v a -> (a -> m b) -> m () 822 | forM_ as f = mapM_ f as 823 | {-# INLINE forM_ #-} 824 | 825 | -- Zipping 826 | -- ------- 827 | 828 | -- | /O(min(m,n))/ Zip two vectors with the given function. 829 | zipWith :: (G.Vector va a, G.Vector vb b) 830 | => (a -> b -> c) -> va a -> vb b -> Vector c 831 | zipWith k a b = boxed (G.unstream (Stream.zipWith k (G.stream a) (G.stream b))) 832 | {-# INLINE zipWith #-} 833 | 834 | -- | Zip three vectors with the given function. 835 | zipWith3 :: (G.Vector va a, G.Vector vb b, G.Vector vc c) 836 | => (a -> b -> c -> d) -> va a -> vb b -> vc c -> Vector d 837 | zipWith3 k a b c = boxed (G.unstream (Stream.zipWith3 k (G.stream a) (G.stream b) (G.stream c))) 838 | {-# INLINE zipWith3 #-} 839 | 840 | zipWith4 :: (G.Vector va a, G.Vector vb b, G.Vector vc c, G.Vector vd d) 841 | => (a -> b -> c -> d -> e) -> va a -> vb b -> vc c -> vd d -> Vector e 842 | zipWith4 k a b c d = boxed (G.unstream (Stream.zipWith4 k (G.stream a) (G.stream b) (G.stream c) (G.stream d))) 843 | {-# INLINE zipWith4 #-} 844 | 845 | zipWith5 :: (G.Vector va a, G.Vector vb b, G.Vector vc c, G.Vector vd d, G.Vector ve e) 846 | => (a -> b -> c -> d -> e -> f) -> va a -> vb b -> vc c -> vd d -> ve e -> Vector f 847 | zipWith5 k a b c d e = boxed (G.unstream (Stream.zipWith5 k (G.stream a) (G.stream b) (G.stream c) (G.stream d) (G.stream e))) 848 | {-# INLINE zipWith5 #-} 849 | 850 | zipWith6 :: (G.Vector va a, G.Vector vb b, G.Vector vc c, G.Vector vd d, G.Vector ve e, G.Vector vf f) 851 | => (a -> b -> c -> d -> e -> f -> g) -> va a -> vb b -> vc c -> vd d -> ve e -> vf f -> Vector g 852 | zipWith6 k a b c d e f = boxed (G.unstream (Stream.zipWith6 k (G.stream a) (G.stream b) (G.stream c) (G.stream d) (G.stream e) (G.stream f))) 853 | {-# INLINE zipWith6 #-} 854 | 855 | 856 | -- | /O(min(m,n))/ Zip two vectors with a function that also takes the 857 | -- elements' indices. 858 | 859 | izipWith :: (G.Vector va a, G.Vector vb b) 860 | => (Int -> a -> b -> c) -> va a -> vb b -> Vector c 861 | izipWith f xs ys = boxed $ G.unstream $ 862 | Stream.zipWith (uncurry f) (Stream.indexed (G.stream xs)) (G.stream ys) 863 | 864 | {-# INLINE izipWith #-} 865 | 866 | -- | Zip three vectors and their indices with the given function. 867 | izipWith3 :: (G.Vector va a, G.Vector vb b, G.Vector vc c) 868 | => (Int -> a -> b -> c -> d) -> va a -> vb b -> vc c -> Vector d 869 | izipWith3 f xs ys zs = boxed $ G.unstream $ 870 | Stream.zipWith3 (uncurry f) (Stream.indexed (G.stream xs)) (G.stream ys) (G.stream zs) 871 | {-# INLINE izipWith3 #-} 872 | 873 | izipWith4 :: (G.Vector va a, G.Vector vb b, G.Vector vc c, G.Vector vd d) 874 | => (Int -> a -> b -> c -> d -> e) -> va a -> vb b -> vc c -> vd d -> Vector e 875 | izipWith4 f xs ys zs ws = boxed $ G.unstream $ 876 | Stream.zipWith4 (uncurry f) (Stream.indexed (G.stream xs)) (G.stream ys) (G.stream zs) (G.stream ws) 877 | {-# INLINE izipWith4 #-} 878 | 879 | izipWith5 :: (G.Vector va a, G.Vector vb b, G.Vector vc c, G.Vector vd d, G.Vector ve e) 880 | => (Int -> a -> b -> c -> d -> e -> f) -> va a -> vb b -> vc c -> vd d -> ve e -> Vector f 881 | izipWith5 k a b c d e = boxed (G.unstream (Stream.zipWith5 (uncurry k) (Stream.indexed (G.stream a)) (G.stream b) (G.stream c) (G.stream d) (G.stream e))) 882 | {-# INLINE izipWith5 #-} 883 | 884 | izipWith6 :: (G.Vector va a, G.Vector vb b, G.Vector vc c, G.Vector vd d, G.Vector ve e, G.Vector vf f) 885 | => (Int -> a -> b -> c -> d -> e -> f -> g) -> va a -> vb b -> vc c -> vd d -> ve e -> vf f -> Vector g 886 | izipWith6 k a b c d e f = boxed (G.unstream (Stream.zipWith6 (uncurry k) (Stream.indexed (G.stream a)) (G.stream b) (G.stream c) (G.stream d) (G.stream e) (G.stream f))) 887 | {-# INLINE izipWith6 #-} 888 | 889 | -- | Elementwise pairing of array elements. 890 | zip :: (G.Vector va a, G.Vector vb b) 891 | => va a -> vb b -> Vector (a, b) 892 | -- zip a b = mix (H.V a b) -- we would need to trim appropriately, and this would likely interfere with streaming. TODO: fix up and benchmark? 893 | zip = zipWith (,) 894 | {-# INLINE zip #-} 895 | 896 | -- | zip together three vectors into a vector of triples 897 | zip3 :: (G.Vector va a, G.Vector vb b, G.Vector vc c) 898 | => va a -> vb b -> vc c -> Vector (a, b, c) 899 | zip3 = zipWith3 (,,) 900 | {-# INLINE zip3 #-} 901 | 902 | zip4 :: (G.Vector va a, G.Vector vb b, G.Vector vc c, G.Vector vd d) 903 | => va a -> vb b -> vc c -> vd d -> Vector (a, b, c, d) 904 | zip4 = zipWith4 (,,,) 905 | {-# INLINE zip4 #-} 906 | 907 | zip5 :: (G.Vector va a, G.Vector vb b, G.Vector vc c, G.Vector vd d, G.Vector ve e) 908 | => va a -> vb b -> vc c -> vd d -> ve e -> Vector (a, b, c, d, e) 909 | zip5 = zipWith5 (,,,,) 910 | {-# INLINE zip5 #-} 911 | 912 | zip6 :: (G.Vector va a, G.Vector vb b, G.Vector vc c, G.Vector vd d, G.Vector ve e, G.Vector vf f) 913 | => va a -> vb b -> vc c -> vd d -> ve e -> vf f -> Vector (a, b, c, d, e, f) 914 | zip6 = zipWith6 (,,,,,) 915 | {-# INLINE zip6 #-} 916 | 917 | -- Unzipping 918 | -- --------- 919 | 920 | -- | /O(min(m,n))/ Unzip a vector of pairs. 921 | unzip :: G.Vector v (a, b) => v (a, b) -> (Vector a, Vector b) 922 | unzip v = (map fst v, map snd v) 923 | {-# INLINE unzip #-} 924 | 925 | unzip3 :: G.Vector v (a, b, c) => v (a, b, c) -> (Vector a, Vector b, Vector c) 926 | unzip3 xs = (map (\(a, _, _) -> a) xs, 927 | map (\(_, b, _) -> b) xs, 928 | map (\(_, _, c) -> c) xs) 929 | {-# INLINE unzip3 #-} 930 | 931 | unzip4 :: G.Vector v (a, b, c, d) => v (a, b, c, d) -> (Vector a, Vector b, Vector c, Vector d) 932 | unzip4 xs = (map (\(a, _, _, _) -> a) xs, 933 | map (\(_, b, _, _) -> b) xs, 934 | map (\(_, _, c, _) -> c) xs, 935 | map (\(_, _, _, d) -> d) xs) 936 | {-# INLINE unzip4 #-} 937 | 938 | unzip5 :: G.Vector v (a, b, c, d, e) => v (a, b, c, d, e) -> (Vector a, Vector b, Vector c, Vector d, Vector e) 939 | unzip5 xs = (map (\(a, _, _, _, _) -> a) xs, 940 | map (\(_, b, _, _, _) -> b) xs, 941 | map (\(_, _, c, _, _) -> c) xs, 942 | map (\(_, _, _, d, _) -> d) xs, 943 | map (\(_, _, _, _, e) -> e) xs) 944 | {-# INLINE unzip5 #-} 945 | 946 | unzip6 :: G.Vector v (a, b, c, d, e, f) => v (a, b, c, d, e, f) -> (Vector a, Vector b, Vector c, Vector d, Vector e, Vector f) 947 | unzip6 xs = (map (\(a, _, _, _, _, _) -> a) xs, 948 | map (\(_, b, _, _, _, _) -> b) xs, 949 | map (\(_, _, c, _, _, _) -> c) xs, 950 | map (\(_, _, _, d, _, _) -> d) xs, 951 | map (\(_, _, _, _, e, _) -> e) xs, 952 | map (\(_, _, _, _, _, f) -> f) xs) 953 | {-# INLINE unzip6 #-} 954 | 955 | -- Monadic zipping 956 | -- --------------- 957 | 958 | -- | /O(min(m,n))/ Zip the two vectors with the monadic action and yield a 959 | -- vector of results 960 | zipWithM :: (Monad m, G.Vector va a, G.Vector vb b) => (a -> b -> m c) -> va a -> vb b -> m (Vector c) 961 | zipWithM f as bs = unstreamM $ Stream.zipWithM f (G.stream as) (G.stream bs) 962 | {-# INLINE zipWithM #-} 963 | 964 | 965 | -- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the 966 | -- results 967 | zipWithM_ :: (Monad m, G.Vector va a, G.Vector vb b) => (a -> b -> m c) -> va a -> vb b -> m () 968 | zipWithM_ f as bs = Stream.zipWithM_ f (G.stream as) (G.stream bs) 969 | {-# INLINE zipWithM_ #-} 970 | 971 | -- Filtering 972 | -- --------- 973 | 974 | -- | /O(n)/ Drop elements that do not satisfy the predicate 975 | filter :: Mixed u v a => (a -> Bool) -> v a -> Vector a 976 | {-# INLINE filter #-} 977 | filter f = mix . G.filter f 978 | 979 | -- | /O(n)/ Drop elements that do not satisfy the predicate which is applied to 980 | -- values and their indices 981 | ifilter :: Mixed u v a => (Int -> a -> Bool) -> v a -> Vector a 982 | ifilter f = mix . G.ifilter f 983 | {-# INLINE ifilter #-} 984 | 985 | -- | /O(n)/ Drop elements that do not satisfy the monadic predicate 986 | filterM :: (Monad m, Mixed u v a) => (a -> m Bool) -> v a -> m (Vector a) 987 | filterM f = liftM mix . G.filterM f 988 | {-# INLINE filterM #-} 989 | 990 | -- | /O(n)/ Yield the longest prefix of elements satisfying the predicate 991 | -- without copying. 992 | takeWhile :: Mixed u v a => (a -> Bool) -> v a -> Vector a 993 | takeWhile f = mix . G.takeWhile f 994 | {-# INLINE takeWhile #-} 995 | 996 | -- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate 997 | -- without copying. 998 | dropWhile :: Mixed u v a => (a -> Bool) -> v a -> Vector a 999 | dropWhile f = mix . G.dropWhile f 1000 | {-# INLINE dropWhile #-} 1001 | 1002 | -- Parititioning 1003 | -- ------------- 1004 | 1005 | -- | /O(n)/ Split the vector in two parts, the first one containing those 1006 | -- elements that satisfy the predicate and the second one those that don't. The 1007 | -- relative order of the elements is preserved at the cost of a sometimes 1008 | -- reduced performance compared to 'unstablePartition'. 1009 | partition :: Mixed u v a => (a -> Bool) -> v a -> (Vector a, Vector a) 1010 | partition f as = case G.partition f as of 1011 | (l,r) -> (mix l, mix r) 1012 | {-# INLINE partition #-} 1013 | 1014 | -- | /O(n)/ Split the vector in two parts, the first one containing those 1015 | -- elements that satisfy the predicate and the second one those that don't. 1016 | -- The order of the elements is not preserved but the operation is often 1017 | -- faster than 'partition'. 1018 | unstablePartition :: Mixed u v a => (a -> Bool) -> v a -> (Vector a, Vector a) 1019 | unstablePartition f as = case G.unstablePartition f as of 1020 | (l,r) -> (mix l, mix r) 1021 | {-# INLINE unstablePartition #-} 1022 | 1023 | -- | /O(n)/ Split the vector into the longest prefix of elements that satisfy 1024 | -- the predicate and the rest without copying. 1025 | span :: Mixed u v a => (a -> Bool) -> v a -> (Vector a, Vector a) 1026 | span f as = case G.span f as of 1027 | (l,r) -> (mix l, mix r) 1028 | {-# INLINE span #-} 1029 | 1030 | -- | /O(n)/ Split the vector into the longest prefix of elements that do not 1031 | -- satisfy the predicate and the rest without copying. 1032 | break :: (a -> Bool) -> Vector a -> (Vector a, Vector a) 1033 | break f as = case G.break f as of 1034 | (l,r) -> (mix l, mix r) 1035 | {-# INLINE break #-} 1036 | 1037 | -- Searching 1038 | -- --------- 1039 | 1040 | infix 4 `elem` 1041 | -- | /O(n)/ Check if the vector contains an element 1042 | elem :: (G.Vector v a, Eq a) => a -> v a -> Bool 1043 | elem = G.elem 1044 | {-# INLINE elem #-} 1045 | 1046 | infix 4 `notElem` 1047 | -- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem') 1048 | notElem :: (G.Vector v a, Eq a) => a -> v a -> Bool 1049 | notElem = G.notElem 1050 | {-# INLINE notElem #-} 1051 | 1052 | -- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing' 1053 | -- if no such element exists. 1054 | find :: (G.Vector v a) => (a -> Bool) -> v a -> Maybe a 1055 | find = G.find 1056 | {-# INLINE find #-} 1057 | 1058 | -- | /O(n)/ Yield 'Just' the index of the first element matching the predicate 1059 | -- or 'Nothing' if no such element exists. 1060 | findIndex :: G.Vector v a => (a -> Bool) -> v a -> Maybe Int 1061 | findIndex = G.findIndex 1062 | {-# INLINE findIndex #-} 1063 | 1064 | -- | /O(n)/ Yield the indices of elements satisfying the predicate in ascending 1065 | -- order. 1066 | findIndices :: G.Vector v a => (a -> Bool) -> v a -> Vector Int 1067 | findIndices f = unboxed . G.unstream 1068 | . Stream.inplace (MStream.map fst . MStream.filter (f . snd) . MStream.indexed) 1069 | . G.stream 1070 | {-# INLINE findIndices #-} 1071 | 1072 | -- | /O(n)/ Yield 'Just' the index of the first occurence of the given element or 1073 | -- 'Nothing' if the vector does not contain the element. This is a specialised 1074 | -- version of 'findIndex'. 1075 | elemIndex :: (G.Vector v a, Eq a) => a -> v a -> Maybe Int 1076 | elemIndex = G.elemIndex 1077 | {-# INLINE elemIndex #-} 1078 | 1079 | -- | /O(n)/ Yield the indices of all occurences of the given element in 1080 | -- ascending order. This is a specialised version of 'findIndices'. 1081 | elemIndices :: (G.Vector v a, Eq a) => a -> v a -> Vector Int 1082 | elemIndices x = findIndices (x==) 1083 | {-# INLINE elemIndices #-} 1084 | 1085 | -- Folding 1086 | -- ------- 1087 | 1088 | -- | /O(n)/ Left fold 1089 | foldl :: G.Vector v b => (a -> b -> a) -> a -> v b -> a 1090 | foldl = G.foldl 1091 | {-# INLINE foldl #-} 1092 | 1093 | -- | /O(n)/ Left fold on non-empty vectors 1094 | foldl1 :: G.Vector v a => (a -> a -> a) -> v a -> a 1095 | foldl1 = G.foldl1 1096 | {-# INLINE foldl1 #-} 1097 | 1098 | -- | /O(n)/ Left fold with strict accumulator 1099 | foldl' :: G.Vector v b => (a -> b -> a) -> a -> v b -> a 1100 | foldl' = G.foldl' 1101 | {-# INLINE foldl' #-} 1102 | 1103 | -- | /O(n)/ Left fold on non-empty vectors with strict accumulator 1104 | foldl1' :: G.Vector v a => (a -> a -> a) -> v a -> a 1105 | foldl1' = G.foldl1' 1106 | {-# INLINE foldl1' #-} 1107 | 1108 | -- | /O(n)/ Right fold 1109 | foldr :: G.Vector v a => (a -> b -> b) -> b -> v a -> b 1110 | foldr = G.foldr 1111 | {-# INLINE foldr #-} 1112 | 1113 | -- | /O(n)/ Right fold on non-empty vectors 1114 | foldr1 :: G.Vector v a => (a -> a -> a) -> v a -> a 1115 | foldr1 = G.foldr1 1116 | {-# INLINE foldr1 #-} 1117 | 1118 | -- | /O(n)/ Right fold with a strict accumulator 1119 | foldr' :: G.Vector v a => (a -> b -> b) -> b -> v a -> b 1120 | foldr' = G.foldr' 1121 | {-# INLINE foldr' #-} 1122 | 1123 | -- | /O(n)/ Right fold on non-empty vectors with strict accumulator 1124 | foldr1' :: G.Vector v a => (a -> a -> a) -> v a -> a 1125 | foldr1' = G.foldr1' 1126 | {-# INLINE foldr1' #-} 1127 | 1128 | -- | /O(n)/ Left fold (function applied to each element and its index) 1129 | ifoldl :: G.Vector v b => (a -> Int -> b -> a) -> a -> v b -> a 1130 | ifoldl = G.ifoldl 1131 | {-# INLINE ifoldl #-} 1132 | 1133 | -- | /O(n)/ Left fold with strict accumulator (function applied to each element 1134 | -- and its index) 1135 | ifoldl' :: G.Vector v b => (a -> Int -> b -> a) -> a -> v b -> a 1136 | ifoldl' = G.ifoldl' 1137 | {-# INLINE ifoldl' #-} 1138 | 1139 | -- | /O(n)/ Right fold (function applied to each element and its index) 1140 | ifoldr :: G.Vector v a => (Int -> a -> b -> b) -> b -> v a -> b 1141 | ifoldr = G.ifoldr 1142 | {-# INLINE ifoldr #-} 1143 | 1144 | -- | /O(n)/ Right fold with strict accumulator (function applied to each 1145 | -- element and its index) 1146 | ifoldr' :: G.Vector v a => (Int -> a -> b -> b) -> b -> v a -> b 1147 | ifoldr' = G.ifoldr' 1148 | {-# INLINE ifoldr' #-} 1149 | 1150 | -- Specialised folds 1151 | -- ----------------- 1152 | 1153 | -- | /O(n)/ Check if all elements satisfy the predicate. 1154 | all :: G.Vector v a => (a -> Bool) -> v a -> Bool 1155 | all = G.all 1156 | {-# INLINE all #-} 1157 | 1158 | -- | /O(n)/ Check if any element satisfies the predicate. 1159 | any :: G.Vector v a => (a -> Bool) -> v a -> Bool 1160 | {-# INLINE any #-} 1161 | any = G.any 1162 | 1163 | -- | /O(n)/ Check if all elements are 'True' 1164 | and :: G.Vector v Bool => v Bool -> Bool 1165 | and = G.and 1166 | {-# INLINE and #-} 1167 | 1168 | -- | /O(n)/ Check if any element is 'True' 1169 | or :: G.Vector v Bool => v Bool -> Bool 1170 | {-# INLINE or #-} 1171 | or = G.or 1172 | 1173 | -- | /O(n)/ Compute the sum of the elements 1174 | sum :: (G.Vector v a, Num a) => v a -> a 1175 | sum = G.sum 1176 | {-# INLINE sum #-} 1177 | 1178 | -- | /O(n)/ Compute the produce of the elements 1179 | product :: (G.Vector v a, Num a) => v a -> a 1180 | product = G.product 1181 | {-# INLINE product #-} 1182 | 1183 | -- | /O(n)/ Yield the maximum element of the vector. The vector may not be 1184 | -- empty. 1185 | maximum :: (G.Vector v a, Ord a) => v a -> a 1186 | maximum = G.maximum 1187 | {-# INLINE maximum #-} 1188 | 1189 | -- | /O(n)/ Yield the maximum element of the vector according to the given 1190 | -- comparison function. The vector may not be empty. 1191 | maximumBy :: G.Vector v a => (a -> a -> Ordering) -> v a -> a 1192 | maximumBy = G.maximumBy 1193 | {-# INLINE maximumBy #-} 1194 | 1195 | -- | /O(n)/ Yield the minimum element of the vector. The vector may not be 1196 | -- empty. 1197 | minimum :: (G.Vector v a, Ord a) => v a -> a 1198 | minimum = G.minimum 1199 | {-# INLINE minimum #-} 1200 | 1201 | -- | /O(n)/ Yield the minimum element of the vector according to the given 1202 | -- comparison function. The vector may not be empty. 1203 | minimumBy :: G.Vector v a => (a -> a -> Ordering) -> v a -> a 1204 | minimumBy = G.minimumBy 1205 | {-# INLINE minimumBy #-} 1206 | 1207 | -- | /O(n)/ Yield the index of the maximum element of the vector. The vector 1208 | -- may not be empty. 1209 | maxIndex :: (G.Vector v a, Ord a) => v a -> Int 1210 | maxIndex = G.maxIndex 1211 | {-# INLINE maxIndex #-} 1212 | 1213 | -- | /O(n)/ Yield the index of the maximum element of the vector according to 1214 | -- the given comparison function. The vector may not be empty. 1215 | maxIndexBy :: G.Vector v a => (a -> a -> Ordering) -> v a -> Int 1216 | maxIndexBy = G.maxIndexBy 1217 | {-# INLINE maxIndexBy #-} 1218 | 1219 | -- | /O(n)/ Yield the index of the minimum element of the vector. The vector 1220 | -- may not be empty. 1221 | minIndex :: (G.Vector v a, Ord a) => v a -> Int 1222 | minIndex = G.minIndex 1223 | {-# INLINE minIndex #-} 1224 | 1225 | -- | /O(n)/ Yield the index of the minimum element of the vector according to 1226 | -- the given comparison function. The vector may not be empty. 1227 | minIndexBy :: G.Vector v a => (a -> a -> Ordering) -> v a -> Int 1228 | minIndexBy = G.minIndexBy 1229 | {-# INLINE minIndexBy #-} 1230 | 1231 | -- Monadic folds 1232 | -- ------------- 1233 | 1234 | -- | /O(n)/ Monadic fold 1235 | foldM :: (G.Vector v b, Monad m) => (a -> b -> m a) -> a -> v b -> m a 1236 | foldM = G.foldM 1237 | {-# INLINE foldM #-} 1238 | 1239 | -- | /O(n)/ Monadic fold over non-empty vectors 1240 | fold1M :: (G.Vector v a, Monad m) => (a -> a -> m a) -> v a -> m a 1241 | fold1M = G.fold1M 1242 | {-# INLINE fold1M #-} 1243 | 1244 | -- | /O(n)/ Monadic fold with strict accumulator 1245 | foldM' :: (G.Vector v b, Monad m) => (a -> b -> m a) -> a -> v b -> m a 1246 | foldM' = G.foldM' 1247 | {-# INLINE foldM' #-} 1248 | 1249 | -- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator 1250 | fold1M' :: (G.Vector v a, Monad m) => (a -> a -> m a) -> v a -> m a 1251 | fold1M' = G.fold1M' 1252 | {-# INLINE fold1M' #-} 1253 | 1254 | -- | /O(n)/ Monadic fold that discards the result 1255 | foldM_ :: (G.Vector v b, Monad m) => (a -> b -> m a) -> a -> v b -> m () 1256 | foldM_ = G.foldM_ 1257 | {-# INLINE foldM_ #-} 1258 | 1259 | -- | /O(n)/ Monadic fold over non-empty vectors that discards the result 1260 | fold1M_ :: (G.Vector v a, Monad m) => (a -> a -> m a) -> v a -> m () 1261 | fold1M_ = G.fold1M_ 1262 | {-# INLINE fold1M_ #-} 1263 | 1264 | -- | /O(n)/ Monadic fold with strict accumulator that discards the result 1265 | foldM'_ :: (G.Vector v b, Monad m) => (a -> b -> m a) -> a -> v b -> m () 1266 | foldM'_ = G.foldM'_ 1267 | {-# INLINE foldM'_ #-} 1268 | 1269 | -- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator 1270 | -- that discards the result 1271 | fold1M'_ :: (G.Vector v a, Monad m) => (a -> a -> m a) -> v a -> m () 1272 | fold1M'_ = G.fold1M'_ 1273 | {-# INLINE fold1M'_ #-} 1274 | 1275 | -- Monadic sequencing 1276 | -- ------------------ 1277 | 1278 | -- | Evaluate each action and collect the results 1279 | sequence :: (Mixed u v (m a), Monad m) => v (m a) -> m (Vector a) 1280 | sequence = mapM id 1281 | {-# INLINE sequence #-} 1282 | 1283 | -- | Evaluate each action and discard the results 1284 | sequence_ :: (G.Vector v (m a), Monad m) => v (m a) -> m () 1285 | sequence_ = mapM_ id 1286 | {-# INLINE sequence_ #-} 1287 | 1288 | -- Prefix sums (scans) 1289 | -- ------------------- 1290 | 1291 | -- | /O(n)/ Prescan 1292 | -- 1293 | -- @ 1294 | -- prescanl f z = 'init' . 'scanl' f z 1295 | -- @ 1296 | -- 1297 | -- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@ 1298 | -- 1299 | prescanl :: G.Vector v b => (a -> b -> a) -> a -> v b -> Vector a 1300 | prescanl f z = boxed . G.unstream . Stream.inplace (MStream.prescanl f z) . G.stream 1301 | {-# INLINE prescanl #-} 1302 | 1303 | -- | /O(n)/ Prescan with strict accumulator 1304 | prescanl' :: G.Vector v b => (a -> b -> a) -> a -> v b -> Vector a 1305 | prescanl' f z = boxed . G.unstream . Stream.inplace (MStream.prescanl' f z) . G.stream 1306 | {-# INLINE prescanl' #-} 1307 | 1308 | -- | /O(n)/ Scan 1309 | -- 1310 | -- @ 1311 | -- postscanl f z = 'tail' . 'scanl' f z 1312 | -- @ 1313 | -- 1314 | -- Example: @postscanl (+) 0 \<1,2,3,4\> = \<1,3,6,10\>@ 1315 | -- 1316 | postscanl :: G.Vector v b => (a -> b -> a) -> a -> v b -> Vector a 1317 | postscanl f z = boxed . G.unstream . Stream.inplace (MStream.postscanl f z) . G.stream 1318 | {-# INLINE postscanl #-} 1319 | 1320 | -- | /O(n)/ Scan with strict accumulator 1321 | postscanl' :: G.Vector v b => (a -> b -> a) -> a -> v b -> Vector a 1322 | postscanl' f z = boxed . G.unstream . Stream.inplace (MStream.postscanl' f z) . G.stream 1323 | {-# INLINE postscanl' #-} 1324 | 1325 | 1326 | -- | /O(n)/ Haskell-style scan 1327 | -- 1328 | -- > scanl f z = 1329 | -- > where y1 = z 1330 | -- > yi = f y(i-1) x(i-1) 1331 | -- 1332 | -- Example: @scanl (+) 0 \<1,2,3,4\> = \<0,1,3,6,10\>@ 1333 | -- 1334 | 1335 | scanl :: G.Vector v b => (a -> b -> a) -> a -> v b -> Vector a 1336 | scanl f z = boxed . G.unstream . Stream.scanl f z . G.stream 1337 | {-# INLINE scanl #-} 1338 | 1339 | -- | /O(n)/ Haskell-style scan with strict accumulator 1340 | scanl' :: G.Vector v b => (a -> b -> a) -> a -> v b -> Vector a 1341 | scanl' f z = boxed . G.unstream . Stream.scanl' f z . G.stream 1342 | {-# INLINE scanl' #-} 1343 | 1344 | -- | /O(n)/ Scan over a non-empty vector 1345 | -- 1346 | -- > scanl f = 1347 | -- > where y1 = x1 1348 | -- > yi = f y(i-1) xi 1349 | -- 1350 | scanl1 :: Mixed u v a => (a -> a -> a) -> v a -> Vector a 1351 | scanl1 f = mix . G.scanl1 f 1352 | {-# INLINE scanl1 #-} 1353 | 1354 | -- | /O(n)/ Scan over a non-empty vector with a strict accumulator 1355 | scanl1' :: Mixed u v a => (a -> a -> a) -> v a -> Vector a 1356 | scanl1' f = mix . G.scanl1' f 1357 | {-# INLINE scanl1' #-} 1358 | 1359 | -- | /O(n)/ Right-to-left prescan 1360 | -- 1361 | -- @ 1362 | -- prescanr f z = 'reverse' . 'prescanl' (flip f) z . 'reverse' 1363 | -- @ 1364 | -- 1365 | prescanr :: G.Vector v a => (a -> b -> b) -> b -> v a -> Vector b 1366 | prescanr f z = boxed . G.unstreamR . Stream.inplace (MStream.prescanl (flip f) z) . G.streamR 1367 | {-# INLINE prescanr #-} 1368 | 1369 | -- | /O(n)/ Right-to-left prescan with strict accumulator 1370 | prescanr' :: G.Vector v a => (a -> b -> b) -> b -> v a -> Vector b 1371 | {-# INLINE prescanr' #-} 1372 | prescanr' f z = boxed . G.unstreamR . Stream.inplace (MStream.prescanl' (flip f) z) . G.streamR 1373 | 1374 | -- | /O(n)/ Right-to-left scan 1375 | postscanr :: G.Vector v a => (a -> b -> b) -> b -> v a -> Vector b 1376 | postscanr f z = boxed . G.unstreamR . Stream.inplace (MStream.postscanl (flip f) z) . G.streamR 1377 | {-# INLINE postscanr #-} 1378 | 1379 | -- | /O(n)/ Right-to-left scan with strict accumulator 1380 | postscanr' :: G.Vector v a => (a -> b -> b) -> b -> v a -> Vector b 1381 | postscanr' f z = boxed . G.unstreamR . Stream.inplace (MStream.postscanl' (flip f) z) . G.streamR 1382 | {-# INLINE postscanr' #-} 1383 | 1384 | -- | /O(n)/ Right-to-left Haskell-style scan 1385 | scanr :: G.Vector v a => (a -> b -> b) -> b -> v a -> Vector b 1386 | scanr f z = boxed . G.unstreamR . Stream.scanl (flip f) z . G.streamR 1387 | {-# INLINE scanr #-} 1388 | 1389 | 1390 | -- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator 1391 | scanr' :: G.Vector v a => (a -> b -> b) -> b -> v a -> Vector b 1392 | scanr' f z = boxed . G.unstreamR . Stream.scanl' (flip f) z . G.streamR 1393 | 1394 | {-# INLINE scanr' #-} 1395 | 1396 | -- | /O(n)/ Right-to-left scan over a non-empty vector 1397 | scanr1 :: Mixed u v a => (a -> a -> a) -> v a -> Vector a 1398 | {-# INLINE scanr1 #-} 1399 | scanr1 f = mix . G.scanr1 f 1400 | 1401 | -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict 1402 | -- accumulator 1403 | scanr1' :: (a -> a -> a) -> Vector a -> Vector a 1404 | scanr1' f = mix . G.scanr1' f 1405 | {-# INLINE scanr1' #-} 1406 | 1407 | -- Conversions - Lists 1408 | -- ------------------------ 1409 | 1410 | -- | /O(n)/ Convert a vector to a list 1411 | toList :: G.Vector v a => v a -> [a] 1412 | toList = G.toList 1413 | {-# INLINE toList #-} 1414 | 1415 | -- | /O(n)/ Convert a list to a vector 1416 | fromList :: [a] -> Vector a 1417 | fromList = boxed . G.fromList 1418 | {-# INLINE fromList #-} 1419 | 1420 | -- | /O(n)/ Convert the first @n@ elements of a list to a vector 1421 | -- 1422 | -- @ 1423 | -- fromListN n xs = 'fromList' ('take' n xs) 1424 | -- @ 1425 | fromListN :: Int -> [a] -> Vector a 1426 | fromListN n = boxed . G.fromListN n 1427 | {-# INLINE fromListN #-} 1428 | 1429 | -- Conversions - Mutable vectors 1430 | -- ----------------------------- 1431 | 1432 | -- | /O(1)/ Unsafe convert a mutable vector to an immutable one without 1433 | -- copying. The mutable vector may not be used after this operation. 1434 | unsafeFreeze :: (PrimMonad m, Mixed u v a) => u (PrimState m) a -> m (Vector a) 1435 | unsafeFreeze = liftM mix . G.unsafeFreeze 1436 | {-# INLINE unsafeFreeze #-} 1437 | 1438 | -- | /O(1)/ Unsafely convert an immutable vector to a mutable one without 1439 | -- copying. The immutable vector may not be used after this operation. 1440 | unsafeThaw :: (PrimMonad m, Mixed u v a) => v a -> m (MVector (PrimState m) a) 1441 | unsafeThaw = liftM mmix . G.unsafeThaw 1442 | {-# INLINE unsafeThaw #-} 1443 | 1444 | -- | /O(n)/ Yield a mutable copy of the immutable vector. 1445 | thaw :: (PrimMonad m, Mixed u v a) => v a -> m (MVector (PrimState m) a) 1446 | thaw = liftM mmix . G.thaw 1447 | {-# INLINE thaw #-} 1448 | 1449 | -- | /O(n)/ Yield an immutable copy of the mutable vector. 1450 | freeze :: (PrimMonad m, Mixed u v a) => u (PrimState m) a -> m (Vector a) 1451 | freeze = liftM mix . G.freeze 1452 | {-# INLINE freeze #-} 1453 | 1454 | -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must 1455 | -- have the same length. This is not checked. 1456 | unsafeCopy :: (PrimMonad m, Mixed u v a, Mixed u' v' a) => u (PrimState m) a -> v' a -> m () 1457 | unsafeCopy dst src = G.unsafeCopy (mmix dst) (mix src) 1458 | {-# INLINE unsafeCopy #-} 1459 | 1460 | -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must 1461 | -- have the same length. 1462 | copy :: (PrimMonad m, Mixed u v a, Mixed u' v' a) => u (PrimState m) a -> v' a -> m () 1463 | copy dst src = G.copy (mmix dst) (mix src) 1464 | {-# INLINE copy #-} 1465 | 1466 | -- Utilities 1467 | -- --------- 1468 | 1469 | unstreamM :: (Monad m, G.Vector v a) => MStream m a -> m (v a) 1470 | unstreamM s = do 1471 | xs <- MStream.toList s 1472 | return $ G.unstream $ Stream.unsafeFromList (MStream.size s) xs 1473 | {-# INLINE [1] unstreamM #-} 1474 | 1475 | -- We have to make sure that this is strict in the stream but we can't seq on 1476 | -- it while fusion is happening. Hence this ugliness. 1477 | modifyWithStream :: G.Vector v a 1478 | => (forall s. G.Mutable v s a -> Stream b -> ST s ()) 1479 | -> v a -> Stream b -> v a 1480 | {-# INLINE modifyWithStream #-} 1481 | modifyWithStream p v s = G.new (New.modifyWithStream p (G.clone v) s) 1482 | --------------------------------------------------------------------------------