packages feed

biohazard 0.6.13 → 0.6.15

raw patch · 26 files changed

+1412/−1702 lines, 26 filesdep −ListLikedep ~base-preludedep ~vectorPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies removed: ListLike

Dependency ranges changed: base-prelude, vector

API changes (from Hackage documentation)

- Bio.Adna: infix 8 `bang`
- Bio.Adna: instance Data.Aeson.Types.FromJSON.FromJSON Bio.Adna.Mat44D
- Bio.Adna: instance Data.Aeson.Types.ToJSON.ToJSON Bio.Adna.Mat44D
- Bio.Bam.Header: eflagVestigial :: Int
- Bio.Bam.Rec: isVestigial :: BamRec -> Bool
- Bio.Bam.Trim: match_adapter :: Int -> Vector Nucleotides -> Vector Qual -> Vector Nucleotides -> Int
- Bio.Bam.Trim: match_reads :: Int -> Vector Nucleotides -> Vector Qual -> Vector Nucleotides -> Vector Qual -> Int
- Bio.Bam.Trim: merge_overlap :: BamRec -> [Vector Nucleotides] -> BamRec -> [Vector Nucleotides] -> Maybe (BamRec, BamRec, BamRec, Int, Int)
- Bio.Bam.Trim: merge_score :: [Vector Nucleotides] -> [Vector Nucleotides] -> Vector Nucleotides -> Vector Qual -> Vector Nucleotides -> Vector Qual -> Int -> Int
- Bio.Bam.Trim: prim_match_ad :: CInt -> CInt -> Ptr Nucleotides -> Ptr Qual -> Ptr Nucleotides -> IO CInt
- Bio.Bam.Trim: prim_match_reads :: CInt -> CInt -> CInt -> Ptr Nucleotides -> Ptr Qual -> Ptr Nucleotides -> Ptr Qual -> IO CInt
- Bio.Bam.Trim: sanitize_cigar :: (Int, [Cigar]) -> (Int, [Cigar])
- Bio.Bam.Trim: trim_adapter :: BamRec -> [Vector Nucleotides] -> Maybe (BamRec, BamRec, Int, Int)
- Bio.Bam.Trim: trim_back_cigar :: Vector v Cigar => v Cigar -> Int -> (Int, v Cigar)
- Bio.Bam.Trim: trim_cigar :: Int -> [Cigar] -> (Int, [Cigar])
- Bio.Bam.Trim: trim_fwd_cigar :: Vector v Cigar => v Cigar -> Int -> (Int, v Cigar)
- Bio.Base: infixr 8 `pow`
- Bio.Iteratee: class (FoldableLL full item, Monoid full) => ListLike full item | full -> item
- Bio.Iteratee: infixl 1 $==
- Bio.Iteratee.Binary: LSB :: Endian
- Bio.Iteratee.Binary: MSB :: Endian
- Bio.Iteratee.Binary: data Endian
- Bio.Iteratee.Binary: endianRead2 :: ListLike s Word8 => Endian -> Iteratee s m Word16
- Bio.Iteratee.Binary: endianRead3 :: ListLike s Word8 => Endian -> Iteratee s m Word32
- Bio.Iteratee.Binary: endianRead3i :: (Nullable s, ListLike s Word8, Monad m) => Endian -> Iteratee s m Int32
- Bio.Iteratee.Binary: endianRead4 :: ListLike s Word8 => Endian -> Iteratee s m Word32
- Bio.Iteratee.Binary: endianRead8 :: ListLike s Word8 => Endian -> Iteratee s m Word64
- Bio.Iteratee.Binary: instance GHC.Classes.Eq Bio.Iteratee.Binary.Endian
- Bio.Iteratee.Binary: instance GHC.Classes.Ord Bio.Iteratee.Binary.Endian
- Bio.Iteratee.Binary: instance GHC.Enum.Enum Bio.Iteratee.Binary.Endian
- Bio.Iteratee.Binary: instance GHC.Show.Show Bio.Iteratee.Binary.Endian
- Bio.Iteratee.Binary: readWord16be_bs :: Iteratee ByteString m Word16
- Bio.Iteratee.Binary: readWord16le_bs :: Iteratee ByteString m Word16
- Bio.Iteratee.Binary: readWord32be_bs :: Iteratee ByteString m Word32
- Bio.Iteratee.Binary: readWord32le_bs :: Iteratee ByteString m Word32
- Bio.Iteratee.Binary: readWord64be_bs :: Iteratee ByteString m Word64
- Bio.Iteratee.Binary: readWord64le_bs :: Iteratee ByteString m Word64
- Bio.Iteratee.Char: enumLines :: (ListLike s el, StringLike s, Nullable s, Monad m) => Enumeratee s [s] m a
- Bio.Iteratee.Char: enumLinesBS :: (Monad m) => Enumeratee ByteString [ByteString] m a
- Bio.Iteratee.Char: enumWords :: (ListLike s Char, Nullable s, Monad m) => Enumeratee s [s] m a
- Bio.Iteratee.Char: enumWordsBS :: (Monad m) => Enumeratee ByteString [ByteString] m a
- Bio.Iteratee.Char: printLines :: Iteratee String IO ()
- Bio.Iteratee.Char: printLinesUnterminated :: forall s el. (Eq el, Nullable s, StringLike s, ListLike s el) => Iteratee s IO ()
- Bio.Iteratee.Iteratee: infixl 1 $=
- Bio.Iteratee.Iteratee: infixr 0 =$
- Bio.Iteratee.ListLike: breakE :: (ListLike s el, NullPoint s) => (el -> Bool) -> Enumeratee s s m a
- Bio.Iteratee.ListLike: breakStream :: (ListLike s el) => (el -> Bool) -> Iteratee s m s
- Bio.Iteratee.ListLike: chunkLength :: (ListLike s el) => Iteratee s m (Maybe Int)
- Bio.Iteratee.ListLike: concatMapStream :: (Monad m, ListLike s a, NullPoint s) => (a -> t) -> Enumeratee s t m r
- Bio.Iteratee.ListLike: concatMapStreamM :: (Monad m, ListLike s a, NullPoint s) => (a -> m t) -> Enumeratee s t m r
- Bio.Iteratee.ListLike: countConsumed :: forall a s el m n. (Monad m, ListLike s el, Nullable s, Integral n) => Iteratee s m a -> Iteratee s m (a, n)
- Bio.Iteratee.ListLike: dropStream :: (Nullable s, ListLike s el) => Int -> Iteratee s m ()
- Bio.Iteratee.ListLike: dropWhileStream :: (ListLike s el) => (el -> Bool) -> Iteratee s m ()
- Bio.Iteratee.ListLike: enumPureNChunk :: (Monad m, ListLike s el) => s -> Int -> Enumerator s m a
- Bio.Iteratee.ListLike: enumWith :: (Monad m, Nullable s, ListLike s el) => Iteratee s m a -> Iteratee s m b -> Iteratee s m (a, b)
- Bio.Iteratee.ListLike: filterStream :: (NullPoint s, ListLike s el) => (el -> Bool) -> Enumeratee s s m a
- Bio.Iteratee.ListLike: filterStreamM :: (Monad m, ListLike s a, Nullable s) => (a -> m Bool) -> Enumeratee s s m r
- Bio.Iteratee.ListLike: foldStream :: ListLike s el => (a -> el -> a) -> a -> Iteratee s m a
- Bio.Iteratee.ListLike: foldStreamM :: (Monad m, Nullable s, ListLike s a) => (b -> a -> m b) -> b -> Iteratee s m b
- Bio.Iteratee.ListLike: groupStreamBy :: (Monad m, ListLike l t, Nullable l) => (t -> t -> Bool) -> m (Iteratee l m t2) -> Enumeratee l [t2] m a
- Bio.Iteratee.ListLike: groupStreamOn :: (Monad m, ListLike l e, Eq t1, Nullable l) => (e -> t1) -> (t1 -> m (Iteratee l m t2)) -> Enumeratee l [(t1, t2)] m a
- Bio.Iteratee.ListLike: headStream :: (ListLike s el) => Iteratee s m el
- Bio.Iteratee.ListLike: heads :: (Monad m, Nullable s, ListLike s el, Eq el) => s -> Iteratee s m Int
- Bio.Iteratee.ListLike: isFinished :: (Nullable s) => Iteratee s m Bool
- Bio.Iteratee.ListLike: lastStream :: (ListLike s el, Nullable s) => Iteratee s m el
- Bio.Iteratee.ListLike: lengthStream :: (Num a, ListLike s el) => Iteratee s m a
- Bio.Iteratee.ListLike: mapMaybeStream :: (ListLike s a, NullPoint s, ListLike t b) => (a -> Maybe b) -> Enumeratee s t m r
- Bio.Iteratee.ListLike: mapStream :: (ListLike (s el) el, ListLike (s el') el', NullPoint (s el)) => (el -> el') -> Enumeratee (s el) (s el') m a
- Bio.Iteratee.ListLike: mapStreamM :: (Monad m, ListLike (s el) el, ListLike (s el') el', NullPoint (s el)) => (el -> m el') -> Enumeratee (s el) (s el') m a
- Bio.Iteratee.ListLike: mapStreamM_ :: (Monad m, Nullable s, ListLike s el) => (el -> m b) -> Iteratee s m ()
- Bio.Iteratee.ListLike: mergeByChunks :: (Nullable c2, Nullable c1, ListLike c1 el1, ListLike c2 el2, Monad m) => (c1 -> c2 -> c3) -> (c1 -> c3) -> (c2 -> c3) -> Enumeratee c2 c3 (Iteratee c1 m) a
- Bio.Iteratee.ListLike: mergeStreams :: (ListLike s1 el1, ListLike s2 el2, Nullable s1, Nullable s2, Monad m) => (el1 -> el2 -> b) -> Enumeratee s2 b (Iteratee s1 m) a
- Bio.Iteratee.ListLike: peekStream :: (ListLike s el) => Iteratee s m (Maybe el)
- Bio.Iteratee.ListLike: rigidMapStream :: (ListLike s el, NullPoint s) => (el -> el) -> Enumeratee s s m a
- Bio.Iteratee.ListLike: roll :: (Monad m, Nullable s, ListLike s el, ListLike s' s) => Int -> Int -> Iteratee s m s'
- Bio.Iteratee.ListLike: sequenceStreams_ :: (Monad m, ListLike s el, Nullable s) => [Iteratee s m a] -> Iteratee s m ()
- Bio.Iteratee.ListLike: stream2list :: (Monad m, Nullable s, ListLike s el) => Iteratee s m [el]
- Bio.Iteratee.ListLike: stream2stream :: (Monad m, Nullable s, Monoid s) => Iteratee s m s
- Bio.Iteratee.ListLike: takeFromChunk :: (Nullable s, ListLike s el) => Int -> Iteratee s m s
- Bio.Iteratee.ListLike: takeStream :: (Monad m, Nullable s, ListLike s el) => Int -> Enumeratee s s m a
- Bio.Iteratee.ListLike: takeUpTo :: (Monad m, Nullable s, ListLike s el) => Int -> Enumeratee s s m a
- Bio.Iteratee.ListLike: takeWhileE :: (ListLike s el, NullPoint s) => (el -> Bool) -> Enumeratee s s m a
- Bio.Iteratee.ListLike: tryHead :: (ListLike s el) => Iteratee s m (Maybe el)
- Bio.Iteratee.ListLike: zipStreams :: (Monad m, Nullable s, ListLike s el) => Iteratee s m a -> Iteratee s m b -> Iteratee s m (a, b)
- Bio.Iteratee.ListLike: zipStreams3 :: (Monad m, Nullable s, ListLike s el) => Iteratee s m a -> Iteratee s m b -> Iteratee s m c -> Iteratee s m (a, b, c)
- Bio.Iteratee.ListLike: zipStreams4 :: (Monad m, Nullable s, ListLike s el) => Iteratee s m a -> Iteratee s m b -> Iteratee s m c -> Iteratee s m d -> Iteratee s m (a, b, c, d)
- Bio.Iteratee.ListLike: zipStreams5 :: (Monad m, Nullable s, ListLike s el) => Iteratee s m a -> Iteratee s m b -> Iteratee s m c -> Iteratee s m d -> Iteratee s m e -> Iteratee s m (a, b, c, d, e)
- Bio.Iteratee.ReadableChunk: class (Storable el) => ReadableChunk s el | s -> el
- Bio.Iteratee.ReadableChunk: instance Bio.Iteratee.ReadableChunk.ReadableChunk Data.ByteString.Internal.ByteString GHC.Word.Word8
- Bio.Iteratee.ReadableChunk: instance Bio.Iteratee.ReadableChunk.ReadableChunk Data.ByteString.Lazy.Internal.ByteString GHC.Word.Word8
- Bio.Iteratee.ReadableChunk: instance Bio.Iteratee.ReadableChunk.ReadableChunk [GHC.Types.Char] GHC.Types.Char
- Bio.Iteratee.ReadableChunk: instance Bio.Iteratee.ReadableChunk.ReadableChunk [GHC.Types.Word] GHC.Types.Word
- Bio.Iteratee.ReadableChunk: instance Bio.Iteratee.ReadableChunk.ReadableChunk [GHC.Word.Word16] GHC.Word.Word16
- Bio.Iteratee.ReadableChunk: instance Bio.Iteratee.ReadableChunk.ReadableChunk [GHC.Word.Word32] GHC.Word.Word32
- Bio.Iteratee.ReadableChunk: instance Bio.Iteratee.ReadableChunk.ReadableChunk [GHC.Word.Word8] GHC.Word.Word8
- Bio.Iteratee.ReadableChunk: readFromPtr :: (ReadableChunk s el, MonadIO m) => Ptr el -> Int -> m s
- Bio.PriorityQueue: PQ_Conf :: Int -> FilePath -> PQ_Conf
- Bio.PriorityQueue: [max_mb] :: PQ_Conf -> Int
- Bio.PriorityQueue: [temp_path] :: PQ_Conf -> FilePath
- Bio.PriorityQueue: class Sizeable a
- Bio.PriorityQueue: data PQ a
- Bio.PriorityQueue: data PQ_Conf
- Bio.PriorityQueue: deletePQ :: PQ a -> IO ()
- Bio.PriorityQueue: dequeuePQ :: (Binary a, Ord a, Sizeable a) => PQ a -> IO ()
- Bio.PriorityQueue: enqueuePQ :: (Binary a, Ord a, Sizeable a) => a -> PQ a -> IO ()
- Bio.PriorityQueue: getMinPQ :: (Binary a, Ord a, Sizeable a) => PQ a -> IO (Maybe a)
- Bio.PriorityQueue: makePQ :: (Binary a, Ord a, Sizeable a) => PQ_Conf -> IO (PQ a)
- Bio.PriorityQueue: peekMinPQ :: (Binary a, Ord a, Sizeable a) => PQ a -> IO (Maybe a)
- Bio.PriorityQueue: sizePQ :: (Binary a, Ord a, Sizeable a) => PQ a -> IO Int
- Bio.PriorityQueue: usedBytes :: Sizeable a => a -> Int
- Bio.PriorityQueue: withPQ :: (Binary a, Ord a, Sizeable a) => PQ_Conf -> (PQ a -> IO b) -> IO b
- Bio.Util.Numeric: infixl 5 <#>
+ Bio.Adna: alnFromMd :: Vector_Nucs_half Nucleotides -> Vector Cigar -> [MdOp] -> Vector NPair
+ Bio.Adna: instance Data.Aeson.Types.Class.FromJSON Bio.Adna.Mat44D
+ Bio.Adna: instance Data.Aeson.Types.Class.ToJSON Bio.Adna.Mat44D
+ Bio.Adna: instance GHC.Generics.Constructor Bio.Adna.C1_0DamageParameters
+ Bio.Adna: instance GHC.Generics.Constructor Bio.Adna.C1_0GenDamageParameters
+ Bio.Adna: instance GHC.Generics.Constructor Bio.Adna.C1_0Mat44D
+ Bio.Adna: instance GHC.Generics.Constructor Bio.Adna.C1_0NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Constructor Bio.Adna.C1_1GenDamageParameters
+ Bio.Adna: instance GHC.Generics.Constructor Bio.Adna.C1_2GenDamageParameters
+ Bio.Adna: instance GHC.Generics.Datatype Bio.Adna.D1DamageParameters
+ Bio.Adna: instance GHC.Generics.Datatype Bio.Adna.D1GenDamageParameters
+ Bio.Adna: instance GHC.Generics.Datatype Bio.Adna.D1Mat44D
+ Bio.Adna: instance GHC.Generics.Datatype Bio.Adna.D1NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_0DamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_0NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_1DamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_1NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_2DamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_2NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_3DamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_3NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_4DamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_4NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_5DamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_5NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_6DamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_6NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_7NewDamageParameters
+ Bio.Adna: instance GHC.Generics.Selector Bio.Adna.S1_0_8NewDamageParameters
+ Bio.Bam.Header: eflagAlternative :: Int
+ Bio.Bam.Header: eflagExactIndex :: Int
+ Bio.Bam.Pileup: instance GHC.Generics.Constructor Bio.Bam.Pileup.C1_0CallStats
+ Bio.Bam.Pileup: instance GHC.Generics.Constructor Bio.Bam.Pileup.C1_0IndelVariant
+ Bio.Bam.Pileup: instance GHC.Generics.Datatype Bio.Bam.Pileup.D1CallStats
+ Bio.Bam.Pileup: instance GHC.Generics.Datatype Bio.Bam.Pileup.D1IndelVariant
+ Bio.Bam.Pileup: instance GHC.Generics.Selector Bio.Bam.Pileup.S1_0_0CallStats
+ Bio.Bam.Pileup: instance GHC.Generics.Selector Bio.Bam.Pileup.S1_0_0IndelVariant
+ Bio.Bam.Pileup: instance GHC.Generics.Selector Bio.Bam.Pileup.S1_0_1CallStats
+ Bio.Bam.Pileup: instance GHC.Generics.Selector Bio.Bam.Pileup.S1_0_1IndelVariant
+ Bio.Bam.Pileup: instance GHC.Generics.Selector Bio.Bam.Pileup.S1_0_2CallStats
+ Bio.Bam.Pileup: instance GHC.Generics.Selector Bio.Bam.Pileup.S1_0_3CallStats
+ Bio.Bam.Rec: isAlternative :: BamRec -> Bool
+ Bio.Bam.Rec: isExactIndex :: BamRec -> Bool
+ Bio.Bam.Trim: find_merge :: [Vector Nucleotides] -> [Vector Nucleotides] -> Vector Nucleotides -> Vector Qual -> Vector Nucleotides -> Vector Qual -> (Int, Int, Int)
+ Bio.Bam.Trim: find_trim :: [Vector Nucleotides] -> Vector Nucleotides -> Vector Qual -> (Int, Int, Int)
+ Bio.Bam.Trim: mergeBam :: Int -> Int -> [Vector Nucleotides] -> [Vector Nucleotides] -> BamRec -> BamRec -> [BamRec]
+ Bio.Bam.Trim: merged_qual :: (Vector v Nucleotides, Vector v Qual) => Word8 -> Int -> v Nucleotides -> v Qual -> v Nucleotides -> v Qual -> v Qual
+ Bio.Bam.Trim: merged_seq :: (Vector v Nucleotides, Vector v Qual) => Int -> v Nucleotides -> v Qual -> v Nucleotides -> v Qual -> v Nucleotides
+ Bio.Bam.Trim: trimBam :: Int -> Int -> [Vector Nucleotides] -> BamRec -> [BamRec]
+ Bio.Iteratee.Builder: BclNucsWide :: BclSpecialType
+ Bio.Iteratee.Bytes: LSB :: Endian
+ Bio.Iteratee.Bytes: MSB :: Endian
+ Bio.Iteratee.Bytes: data Endian
+ Bio.Iteratee.Bytes: dropStreamBS :: Int -> Iteratee Bytes m ()
+ Bio.Iteratee.Bytes: dropWhileStreamBS :: (Word8 -> Bool) -> Iteratee Bytes m ()
+ Bio.Iteratee.Bytes: endianRead2 :: Endian -> Iteratee Bytes m Word16
+ Bio.Iteratee.Bytes: endianRead3 :: Endian -> Iteratee Bytes m Word32
+ Bio.Iteratee.Bytes: endianRead3i :: Monad m => Endian -> Iteratee Bytes m Int32
+ Bio.Iteratee.Bytes: endianRead4 :: Endian -> Iteratee Bytes m Word32
+ Bio.Iteratee.Bytes: endianRead8 :: Endian -> Iteratee Bytes m Word64
+ Bio.Iteratee.Bytes: enumLinesBS :: Monad m => Enumeratee Bytes [Bytes] m a
+ Bio.Iteratee.Bytes: enumWordsBS :: Monad m => Enumeratee Bytes [Bytes] m a
+ Bio.Iteratee.Bytes: headStreamBS :: Iteratee Bytes m Word8
+ Bio.Iteratee.Bytes: instance GHC.Classes.Eq Bio.Iteratee.Bytes.Endian
+ Bio.Iteratee.Bytes: instance GHC.Classes.Ord Bio.Iteratee.Bytes.Endian
+ Bio.Iteratee.Bytes: instance GHC.Enum.Enum Bio.Iteratee.Bytes.Endian
+ Bio.Iteratee.Bytes: instance GHC.Show.Show Bio.Iteratee.Bytes.Endian
+ Bio.Iteratee.Bytes: peekStreamBS :: Iteratee Bytes m (Maybe Word8)
+ Bio.Iteratee.Bytes: takeStreamBS :: Monad m => Int -> Enumeratee Bytes Bytes m a
+ Bio.Iteratee.Bytes: tryHeadBS :: Iteratee Bytes m (Maybe Word8)
+ Bio.Iteratee.List: breakE :: (el -> Bool) -> Enumeratee [el] [el] m a
+ Bio.Iteratee.List: breakStream :: (el -> Bool) -> Iteratee [el] m [el]
+ Bio.Iteratee.List: chunkLength :: Iteratee [el] m (Maybe Int)
+ Bio.Iteratee.List: concatMapStream :: Monoid t => (a -> t) -> Enumeratee [a] t m r
+ Bio.Iteratee.List: concatMapStreamM :: Monad m => (a -> m t) -> Enumeratee [a] t m r
+ Bio.Iteratee.List: countConsumed :: (Monad m, Integral n) => Iteratee [el] m a -> Iteratee [el] m (a, n)
+ Bio.Iteratee.List: dropStream :: Int -> Iteratee [el] m ()
+ Bio.Iteratee.List: dropWhileStream :: (el -> Bool) -> Iteratee [el] m ()
+ Bio.Iteratee.List: enumPureNChunk :: Monad m => [el] -> Int -> Enumerator [el] m a
+ Bio.Iteratee.List: enumWith :: Monad m => Iteratee [el] m a -> Iteratee [el] m b -> Iteratee [el] m (a, b)
+ Bio.Iteratee.List: filterStream :: (el -> Bool) -> Enumeratee [el] [el] m a
+ Bio.Iteratee.List: filterStreamM :: Monad m => (a -> m Bool) -> Enumeratee [a] [a] m r
+ Bio.Iteratee.List: foldStream :: (a -> el -> a) -> a -> Iteratee [el] m a
+ Bio.Iteratee.List: foldStreamM :: Monad m => (b -> a -> m b) -> b -> Iteratee [a] m b
+ Bio.Iteratee.List: groupStreamBy :: Monad m => (t -> t -> Bool) -> m (Iteratee [t] m t2) -> Enumeratee [t] [t2] m a
+ Bio.Iteratee.List: groupStreamOn :: (Monad m, Eq t1) => (e -> t1) -> (t1 -> m (Iteratee [e] m t2)) -> Enumeratee [e] [(t1, t2)] m a
+ Bio.Iteratee.List: headStream :: Iteratee [el] m el
+ Bio.Iteratee.List: heads :: (Monad m, Eq el) => [el] -> Iteratee [el] m Int
+ Bio.Iteratee.List: isFinished :: Nullable s => Iteratee s m Bool
+ Bio.Iteratee.List: lastStream :: Iteratee [el] m el
+ Bio.Iteratee.List: lengthStream :: Num a => Iteratee [el] m a
+ Bio.Iteratee.List: mapMaybeStream :: (a -> Maybe b) -> Enumeratee [a] [b] m r
+ Bio.Iteratee.List: mapStream :: (el -> el') -> Enumeratee [el] [el'] m a
+ Bio.Iteratee.List: mapStreamM :: Monad m => (el -> m el') -> Enumeratee [el] [el'] m a
+ Bio.Iteratee.List: mapStreamM_ :: Monad m => (el -> m b) -> Iteratee [el] m ()
+ Bio.Iteratee.List: mergeByChunks :: Monad m => ([el1] -> [el2] -> c3) -> ([el1] -> c3) -> ([el2] -> c3) -> Enumeratee [el2] c3 (Iteratee [el1] m) a
+ Bio.Iteratee.List: mergeStreams :: Monad m => (el1 -> el2 -> b) -> Enumeratee [el2] b (Iteratee [el1] m) a
+ Bio.Iteratee.List: peekStream :: Iteratee [el] m (Maybe el)
+ Bio.Iteratee.List: roll :: Monad m => Int -> Int -> Iteratee [el] m [[el]]
+ Bio.Iteratee.List: sequenceStreams_ :: Monad m => [Iteratee [el] m a] -> Iteratee [el] m ()
+ Bio.Iteratee.List: stream2list :: Monad m => Iteratee [el] m [el]
+ Bio.Iteratee.List: stream2stream :: (Monad m, Nullable s, Monoid s) => Iteratee s m s
+ Bio.Iteratee.List: takeFromChunk :: Int -> Iteratee [el] m [el]
+ Bio.Iteratee.List: takeStream :: Monad m => Int -> Enumeratee [el] [el] m a
+ Bio.Iteratee.List: takeUpTo :: Monad m => Int -> Enumeratee [el] [el] m a
+ Bio.Iteratee.List: takeWhileE :: (el -> Bool) -> Enumeratee [el] [el] m a
+ Bio.Iteratee.List: tryHead :: Iteratee [el] m (Maybe el)
+ Bio.Iteratee.List: zipStreams :: Monad m => Iteratee [el] m a -> Iteratee [el] m b -> Iteratee [el] m (a, b)
+ Bio.Iteratee.List: zipStreams3 :: Monad m => Iteratee [el] m a -> Iteratee [el] m b -> Iteratee [el] m c -> Iteratee [el] m (a, b, c)
+ Bio.Iteratee.List: zipStreams4 :: Monad m => Iteratee [el] m a -> Iteratee [el] m b -> Iteratee [el] m c -> Iteratee [el] m d -> Iteratee [el] m (a, b, c, d)
+ Bio.Iteratee.List: zipStreams5 :: Monad m => Iteratee [el] m a -> Iteratee [el] m b -> Iteratee [el] m c -> Iteratee [el] m d -> Iteratee [el] m e -> Iteratee [el] m (a, b, c, d, e)
- Bio.Bam.Rmdup: check_sort :: Monad m => String -> Enumeratee [BamRec] [BamRec] m a
+ Bio.Bam.Rmdup: check_sort :: Monad m => (a -> BamRec) -> String -> Enumeratee [a] [a] m b
- Bio.Bam.Rmdup: rmdup :: (Monad m, Ord l) => (BamRec -> l) -> Bool -> Collapse -> Enumeratee [BamRec] [BamRec] m r
+ Bio.Bam.Rmdup: rmdup :: (Monad m, Ord l) => (BamRec -> l) -> Bool -> Collapse -> Enumeratee [BamRec] [(Int, BamRec)] m r
- Bio.Bam.Trim: mergeTrimBam :: Monad m => [Vector Nucleotides] -> [Vector Nucleotides] -> Enumeratee [BamRec] [BamRec] m a
+ Bio.Bam.Trim: mergeTrimBam :: Monad m => Int -> Int -> [Vector Nucleotides] -> [Vector Nucleotides] -> Enumeratee [BamRec] [BamRec] m a
- Bio.Iteratee: mergeSortStreams :: (Monad m, ListLike s a, Nullable s) => (a -> a -> Ordering' a) -> Enumeratee s s (Iteratee s m) b
+ Bio.Iteratee: mergeSortStreams :: Monad m => (a -> a -> Ordering' a) -> Enumeratee [a] [a] (Iteratee [a] m) b
- Bio.Iteratee: progressGen :: (MonadIO m, NullPoint s, ListLike s a) => (Int -> a -> String) -> Int -> (String -> IO ()) -> Enumeratee s s m b
+ Bio.Iteratee: progressGen :: MonadIO m => (Int -> a -> String) -> Int -> (String -> IO ()) -> Enumeratee [a] [a] m b
- Bio.Iteratee: progressNum :: (MonadIO m, NullPoint s, ListLike s a) => String -> Int -> (String -> IO ()) -> Enumeratee s s m b
+ Bio.Iteratee: progressNum :: MonadIO m => String -> Int -> (String -> IO ()) -> Enumeratee [a] [a] m b
- Bio.Iteratee: progressPos :: (MonadIO m, ListLike s a, NullPoint s) => (a -> (Refseq, Int)) -> String -> Refs -> Int -> (String -> IO ()) -> Enumeratee s s m b
+ Bio.Iteratee: progressPos :: MonadIO m => (a -> (Refseq, Int)) -> String -> Refs -> Int -> (String -> IO ()) -> Enumeratee [a] [a] m b
- Bio.Iteratee: stream2vector :: (MonadIO m, ListLike s a, Nullable s, Vector v a) => Iteratee s m (v a)
+ Bio.Iteratee: stream2vector :: (MonadIO m, Vector v a) => Iteratee [a] m (v a)
- Bio.Iteratee: stream2vectorN :: (MonadIO m, ListLike s a, Nullable s, Vector v a) => Int -> Iteratee s m (v a)
+ Bio.Iteratee: stream2vectorN :: (MonadIO m, Vector v a) => Int -> Iteratee [a] m (v a)
- Bio.Iteratee.Exception: displayException :: e -> String
+ Bio.Iteratee.Exception: displayException :: Exception e => e -> String
- Bio.Iteratee.Exception: fromException :: SomeException -> Maybe e
+ Bio.Iteratee.Exception: fromException :: Exception e => SomeException -> Maybe e
- Bio.Iteratee.Exception: toException :: e -> SomeException
+ Bio.Iteratee.Exception: toException :: Exception e => e -> SomeException
- Bio.Iteratee.IO: enumFd :: forall s el m a. (NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Fd -> Enumerator s m a
+ Bio.Iteratee.IO: enumFd :: (MonadIO m, MonadMask m) => Int -> Fd -> Enumerator Bytes m a
- Bio.Iteratee.IO: enumFdRandom :: forall s el m a. (NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Fd -> Enumerator s m a
+ Bio.Iteratee.IO: enumFdRandom :: (MonadIO m, MonadMask m) => Int -> Fd -> Enumerator Bytes m a
- Bio.Iteratee.IO: enumFile :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) => Int -> FilePath -> Enumerator s m a
+ Bio.Iteratee.IO: enumFile :: (MonadIO m, MonadMask m) => Int -> FilePath -> Enumerator Bytes m a
- Bio.Iteratee.IO: enumFileRandom :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) => Int -> FilePath -> Enumerator s m a
+ Bio.Iteratee.IO: enumFileRandom :: (MonadIO m, MonadMask m) => Int -> FilePath -> Enumerator Bytes m a
- Bio.Iteratee.IO: enumHandle :: forall s el m a. (NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Handle -> Enumerator s m a
+ Bio.Iteratee.IO: enumHandle :: (MonadIO m, MonadMask m) => Int -> Handle -> Enumerator Bytes m a
- Bio.Iteratee.IO: enumHandleRandom :: forall s el m a. (NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Handle -> Enumerator s m a
+ Bio.Iteratee.IO: enumHandleRandom :: (MonadIO m, MonadMask m) => Int -> Handle -> Enumerator Bytes m a
- Bio.Iteratee.IO: fileDriver :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) => Iteratee s m a -> FilePath -> m a
+ Bio.Iteratee.IO: fileDriver :: (MonadIO m, MonadMask m) => Iteratee Bytes m a -> FilePath -> m a
- Bio.Iteratee.IO: fileDriverRandom :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) => Iteratee s m a -> FilePath -> m a
+ Bio.Iteratee.IO: fileDriverRandom :: (MonadIO m, MonadMask m) => Iteratee Bytes m a -> FilePath -> m a
- Bio.Iteratee.IO: fileDriverRandomVBuf :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) => Int -> Iteratee s m a -> FilePath -> m a
+ Bio.Iteratee.IO: fileDriverRandomVBuf :: (MonadIO m, MonadMask m) => Int -> Iteratee Bytes m a -> FilePath -> m a
- Bio.Iteratee.IO: fileDriverVBuf :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) => Int -> Iteratee s m a -> FilePath -> m a
+ Bio.Iteratee.IO: fileDriverVBuf :: (MonadIO m, MonadMask m) => Int -> Iteratee Bytes m a -> FilePath -> m a
- Bio.Iteratee.IO.Fd: enumFd :: forall s el m a. (NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Fd -> Enumerator s m a
+ Bio.Iteratee.IO.Fd: enumFd :: (MonadIO m, MonadMask m) => Int -> Fd -> Enumerator Bytes m a
- Bio.Iteratee.IO.Fd: enumFdCatch :: forall e s el m a. (IException e, NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Fd -> (e -> m (Maybe EnumException)) -> Enumerator s m a
+ Bio.Iteratee.IO.Fd: enumFdCatch :: (IException e, MonadIO m, MonadMask m) => Int -> Fd -> (e -> m (Maybe EnumException)) -> Enumerator Bytes m a
- Bio.Iteratee.IO.Fd: enumFdRandom :: forall s el m a. (NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Fd -> Enumerator s m a
+ Bio.Iteratee.IO.Fd: enumFdRandom :: (MonadIO m, MonadMask m) => Int -> Fd -> Enumerator Bytes m a
- Bio.Iteratee.IO.Fd: enumFile :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) => Int -> FilePath -> Enumerator s m a
+ Bio.Iteratee.IO.Fd: enumFile :: (MonadIO m, MonadMask m) => Int -> FilePath -> Enumerator Bytes m a
- Bio.Iteratee.IO.Fd: enumFileRandom :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) => Int -> FilePath -> Enumerator s m a
+ Bio.Iteratee.IO.Fd: enumFileRandom :: (MonadIO m, MonadMask m) => Int -> FilePath -> Enumerator Bytes m a
- Bio.Iteratee.IO.Fd: fileDriverFd :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) => Int -> Iteratee s m a -> FilePath -> m a
+ Bio.Iteratee.IO.Fd: fileDriverFd :: (MonadIO m, MonadMask m) => Int -> Iteratee Bytes m a -> FilePath -> m a
- Bio.Iteratee.IO.Fd: fileDriverRandomFd :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) => Int -> Iteratee s m a -> FilePath -> m a
+ Bio.Iteratee.IO.Fd: fileDriverRandomFd :: (MonadIO m, MonadMask m) => Int -> Iteratee Bytes m a -> FilePath -> m a
- Bio.Iteratee.IO.Handle: enumFile :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) => Int -> FilePath -> Enumerator s m a
+ Bio.Iteratee.IO.Handle: enumFile :: (MonadIO m, MonadMask m) => Int -> FilePath -> Enumerator Bytes m a
- Bio.Iteratee.IO.Handle: enumFileRandom :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) => Int -> FilePath -> Enumerator s m a
+ Bio.Iteratee.IO.Handle: enumFileRandom :: (MonadIO m, MonadMask m) => Int -> FilePath -> Enumerator Bytes m a
- Bio.Iteratee.IO.Handle: enumHandle :: forall s el m a. (NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Handle -> Enumerator s m a
+ Bio.Iteratee.IO.Handle: enumHandle :: (MonadIO m, MonadMask m) => Int -> Handle -> Enumerator Bytes m a
- Bio.Iteratee.IO.Handle: enumHandleCatch :: forall e s el m a. (IException e, NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Handle -> (e -> m (Maybe EnumException)) -> Enumerator s m a
+ Bio.Iteratee.IO.Handle: enumHandleCatch :: (IException e, MonadIO m, MonadMask m) => Int -> Handle -> (e -> m (Maybe EnumException)) -> Enumerator Bytes m a
- Bio.Iteratee.IO.Handle: enumHandleRandom :: forall s el m a. (NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) => Int -> Handle -> Enumerator s m a
+ Bio.Iteratee.IO.Handle: enumHandleRandom :: (MonadIO m, MonadMask m) => Int -> Handle -> Enumerator Bytes m a
- Bio.Iteratee.IO.Handle: fileDriverHandle :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) => Int -> Iteratee s m a -> FilePath -> m a
+ Bio.Iteratee.IO.Handle: fileDriverHandle :: (MonadIO m, MonadMask m) => Int -> Iteratee Bytes m a -> FilePath -> m a
- Bio.Iteratee.IO.Handle: fileDriverRandomHandle :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) => Int -> Iteratee s m a -> FilePath -> m a
+ Bio.Iteratee.IO.Handle: fileDriverRandomHandle :: (MonadIO m, MonadMask m) => Int -> Iteratee Bytes m a -> FilePath -> m a
- Bio.Prelude: hash :: a -> Int
+ Bio.Prelude: hash :: Hashable a => a -> Int
- Bio.Prelude: hashWithSalt :: Int -> a -> Int
+ Bio.Prelude: hashWithSalt :: Hashable a => Int -> a -> Int

Files

biohazard.cabal view
@@ -1,5 +1,5 @@ Name:                biohazard-Version:             0.6.13+Version:             0.6.15 Synopsis:            bioinformatics support library Description:         This is a collection of modules I separated from                      various bioinformatics tools.  The hope is to make@@ -49,20 +49,17 @@                        Bio.Iteratee,                        Bio.Iteratee.Base,                        Bio.Iteratee.Bgzf,-                       Bio.Iteratee.Binary,                        Bio.Iteratee.Builder,-                       Bio.Iteratee.Char,+                       Bio.Iteratee.Bytes,                        Bio.Iteratee.Exception,                        Bio.Iteratee.IO,                        Bio.Iteratee.IO.Base,                        Bio.Iteratee.IO.Fd,                        Bio.Iteratee.IO.Handle,                        Bio.Iteratee.Iteratee,-                       Bio.Iteratee.ListLike,-                       Bio.Iteratee.ReadableChunk,+                       Bio.Iteratee.List,                        Bio.Iteratee.ZLib,                        Bio.Prelude,-                       Bio.PriorityQueue,                        Bio.TwoBit,                        Bio.Util.Numeric,                        Bio.Util.Zlib@@ -71,7 +68,7 @@                        async                    >= 2.0 && < 2.2,                        attoparsec               >= 0.10 && < 0.14,                        base                     >= 4.6 && < 4.10,-                       base-prelude             == 1.0.*,+                       base-prelude             >= 1.0 && < 1.3,                        binary                   >= 0.7 && < 0.9,                        bytestring               >= 0.10.2 && < 0.11,                        bytestring-mmap          >= 0.2 && < 1.0,@@ -80,7 +77,6 @@                        exceptions               >= 0.6 && < 0.9,                        filepath                 >= 1.3 && < 2.0,                        hashable                 >= 1.0 && < 1.3,-                       ListLike                 >= 3.0 && < 5.0,                        monad-control            == 1.0.*,                        primitive                >= 0.5 && < 0.7,                        random                   >= 1.0 && < 1.2,@@ -91,7 +87,7 @@                        transformers-base        >= 0.4 && < 0.6,                        unix                     >= 2.5 && < 2.8,                        unordered-containers     >= 0.2.3 && < 0.3,-                       vector                   == 0.11.*,+                       vector                   >= 0.11 && < 0.13,                        vector-algorithms        >= 0.3 && < 1.0,                        vector-th-unbox          == 0.2.*,                        zlib                     == 0.6.*
src/Bio/Adna.hs view
@@ -7,6 +7,7 @@     damagePatternsIter,     damagePatternsIterMD,     damagePatternsIter2Bit,+    alnFromMd,      DamageParameters(..),     NewDamageParameters(..),@@ -361,7 +362,7 @@         let b@BamRec{..} = unpackBam br         guard (not $ isUnmapped b)         md <- getMd b-        let pps = aln_from_md b_seq b_cigar md+        let pps = alnFromMd b_seq b_cigar md             ref = U.map fromN $ U.filter ((/=) gap . fst) pps         return (b, ft, ref, pps)) =$     damagePatternsIter 0 rng it@@ -581,8 +582,8 @@  -- | Reconstructs the alignment from query, cigar, and md.  Only -- positions where the query is not gapped are produced.-aln_from_md :: Vector_Nucs_half Nucleotides -> VS.Vector Cigar -> [MdOp] -> U.Vector NPair-aln_from_md qry0 cig0 md0 = U.fromList $ step qry0 cig0 md0+alnFromMd :: Vector_Nucs_half Nucleotides -> VS.Vector Cigar -> [MdOp] -> U.Vector NPair+alnFromMd qry0 cig0 md0 = U.fromList $ step qry0 cig0 md0   where     step qry cig1 md         | G.null qry || G.null cig1 || null md = []
src/Bio/Bam/Fastq.hs view
@@ -99,9 +99,9 @@              | otherwise = Just (i-1)  skipJunk :: Monad m => Iteratee Bytes m ()-skipJunk = peekStream >>= check+skipJunk = peekStreamBS >>= check   where-    check (Just c) | bad c = dropWhileStream (c2w '\n' /=) >> dropStream 1 >> skipJunk+    check (Just c) | bad c = dropWhileStreamBS (c2w '\n' /=) >> dropStreamBS 1 >> skipJunk     check _                = return ()     bad c = c /= c2w '>' && c /= c2w '@' 
src/Bio/Bam/Header.hs view
@@ -38,7 +38,8 @@         flagDuplicate,         eflagTrimmed,         eflagMerged,-        eflagVestigial,+        eflagAlternative,+        eflagExactIndex,          distinctBin, @@ -288,29 +289,31 @@  getRef :: Refs -> Refseq -> BamSQ getRef refs (Refseq i)-    | 0 <= i && fromIntegral i < Z.length refs = Z.index refs (fromIntegral i)-    | otherwise                                = BamSQ "*" 0 []+    | i < fromIntegral (Z.length refs) = Z.index refs (fromIntegral i)+    | otherwise                        = BamSQ "*" 0 []  -flagPaired, flagProperlyPaired, flagUnmapped, flagMateUnmapped, flagReversed, flagMateReversed, flagFirstMate, flagSecondMate,+flagPaired, flagProperlyPaired, flagUnmapped, flagMateUnmapped,+ flagReversed, flagMateReversed, flagFirstMate, flagSecondMate,  flagAuxillary, flagFailsQC, flagDuplicate :: Int -flagPaired = 0x1-flagProperlyPaired = 0x2-flagUnmapped = 0x4-flagMateUnmapped = 0x8-flagReversed = 0x10-flagMateReversed = 0x20-flagFirstMate = 0x40-flagSecondMate = 0x80-flagAuxillary = 0x100-flagFailsQC = 0x200-flagDuplicate = 0x400+flagPaired         =   0x1+flagProperlyPaired =   0x2+flagUnmapped       =   0x4+flagMateUnmapped   =   0x8+flagReversed       =  0x10+flagMateReversed   =  0x20+flagFirstMate      =  0x40+flagSecondMate     =  0x80+flagAuxillary      = 0x100+flagFailsQC        = 0x200+flagDuplicate      = 0x400 -eflagTrimmed, eflagMerged, eflagVestigial :: Int-eflagTrimmed       = 0x1-eflagMerged        = 0x2-eflagVestigial     = 0x4+eflagTrimmed, eflagMerged, eflagAlternative, eflagExactIndex :: Int+eflagTrimmed     = 0x1+eflagMerged      = 0x2+eflagAlternative = 0x4+eflagExactIndex  = 0x8   -- | Compares two sequence names the way samtools does.
src/Bio/Bam/Index.hs view
@@ -175,7 +175,7 @@      switch "CSI\1" = do minshift <- fromIntegral `liftM` endianRead4 LSB                         depth <- fromIntegral `liftM` endianRead4 LSB-                        endianRead4 LSB >>= dropStream . fromIntegral -- aux data+                        endianRead4 LSB >>= dropStreamBS . fromIntegral -- aux data                         nref <- fromIntegral `liftM` endianRead4 LSB                         getIndexArrays nref minshift depth (addOneCheckpoint minshift depth) return 
src/Bio/Bam/Reader.hs view
@@ -173,7 +173,8 @@  isEmptyBam = (\e -> if e then Just (\k -> return $ k mempty) else Nothing) `liftM` isFinished -isPlainBam = (\n -> if n == 4 then Just (joinI . decompressPlain . decodeBam) else Nothing) `liftM` heads "BAM\SOH"+isPlainBam = (\n -> if n == "BAM\SOH" then Just (joinI . decompressPlain . decodeBam) else Nothing)+             `liftM` iGetString 4  -- Interesting... iLookAhead interacts badly with the parallel -- decompression of BGZF.  (The chosen interface doesn't allow the EOF@@ -257,11 +258,12 @@                      refs <- liftBlock get_ref_array                      convStream getBamRaw $ inner $! mmerge meta refs   where-    get_bam_header  = do magic <- heads "BAM\SOH"-                         when (magic /= 4) $ do s <- iGetString 10-                                                fail $ "BAM signature not found: " ++ show magic ++ " " ++ show s+    get_bam_header  = do magic <- iGetString 4 +                         when (magic /= "BAM\SOH") $ do+                                s <- iGetString 10+                                fail $ "BAM signature not found: " ++ show magic ++ " " ++ show s                          hdr_len <- endianRead4 LSB-                         joinI $ takeStream (fromIntegral hdr_len) $ parserToIteratee parseBamMeta+                         joinI $ takeStreamBS (fromIntegral hdr_len) $ parserToIteratee parseBamMeta      get_ref_array = do nref <- endianRead4 LSB                        foldM (\acc _ -> do
src/Bio/Bam/Rec.hs view
@@ -46,7 +46,8 @@     isDuplicate,     isTrimmed,     isMerged,-    isVestigial,+    isAlternative,+    isExactIndex,     type_mask,      progressBam,@@ -59,10 +60,7 @@  import Control.Monad.Primitive      ( unsafePrimToPrim, unsafeInlineIO ) import Foreign.C.Types              ( CInt(..), CSize(..) )-import Foreign.ForeignPtr import Foreign.Marshal.Alloc        ( alloca )-import Foreign.Ptr                  ( Ptr, plusPtr )-import Foreign.Storable             ( peek, poke, peekByteOff, pokeByteOff, Storable(..) )  import qualified Data.ByteString                    as B import qualified Data.ByteString.Char8              as S@@ -278,11 +276,14 @@                      fromIntegral (B.unsafeIndex (raw_data br) $ o+1) `shiftL`  8          getInt32 :: (Num a, Bits a) => Int -> a-        getInt32 o = fromIntegral (B.unsafeIndex (raw_data br) $ o+0)             .|.-                     fromIntegral (B.unsafeIndex (raw_data br) $ o+1) `shiftL`  8 .|.-                     fromIntegral (B.unsafeIndex (raw_data br) $ o+2) `shiftL` 16 .|.-                     fromIntegral (B.unsafeIndex (raw_data br) $ o+3) `shiftL` 24+        getInt32 o = fromIntegral (        B.unsafeIndex (raw_data br) $ o+0 )             .|.+                     fromIntegral (        B.unsafeIndex (raw_data br) $ o+1 ) `shiftL`  8 .|.+                     fromIntegral (        B.unsafeIndex (raw_data br) $ o+2 ) `shiftL` 16 .|.+                     fromIntegral (signed (B.unsafeIndex (raw_data br) $ o+3)) `shiftL` 24 +        signed :: Word8 -> Int8+        signed = fromIntegral+ -- | A collection of extension fields.  The key is actually only two @Char@s, but that proved impractical. -- (Hmm... we could introduce a Key type that is a 16 bit int, then give -- it an @instance IsString@... practical?)@@ -361,7 +362,7 @@  isPaired, isProperlyPaired, isUnmapped, isMateUnmapped, isReversed,     isMateReversed, isFirstMate, isSecondMate, isAuxillary, isFailsQC,-    isDuplicate, isTrimmed, isMerged, isVestigial :: BamRec -> Bool+    isDuplicate, isTrimmed, isMerged, isAlternative, isExactIndex :: BamRec -> Bool  isPaired         = flip testBit  0 . b_flag isProperlyPaired = flip testBit  1 . b_flag@@ -377,7 +378,8 @@  isTrimmed        = flip testBit 0 . extAsInt 0 "FF" isMerged         = flip testBit 1 . extAsInt 0 "FF"-isVestigial      = flip testBit 2 . extAsInt 0 "FF"+isAlternative    = flip testBit 2 . extAsInt 0 "FF"+isExactIndex     = flip testBit 3 . extAsInt 0 "FF"  type_mask :: Int type_mask = flagFirstMate .|. flagSecondMate .|. flagPaired
src/Bio/Bam/Rmdup.hs view
@@ -102,20 +102,20 @@ -- duplicates of each other.  The typical label function would extract -- read groups, libraries or samples. -rmdup :: (Monad m, Ord l) => (BamRec -> l) -> Bool -> Collapse -> Enumeratee [BamRec] [BamRec] m r+rmdup :: (Monad m, Ord l) => (BamRec -> l) -> Bool -> Collapse -> Enumeratee [BamRec] [(Int,BamRec)] m r rmdup label strand_preserved collapse_cfg =     -- Easiest way to go about this:  We simply collect everything that     -- starts at some specific coordinate and group it appropriately.     -- Treat the groups separately, output, go on.-    check_sort "input must be sorted for rmdup to work" ><>+    check_sort id "input must be sorted for rmdup to work" ><>     mapGroups rmdup_group ><>-    check_sort "internal error, output isn't sorted anymore"+    check_sort snd "internal error, output isn't sorted anymore"   where     rmdup_group = nice_sort . do_rmdup label strand_preserved collapse_cfg     same_pos u v = b_cpos u == b_cpos v     b_cpos u = (b_rname u, b_pos u) -    nice_sort x = sortBy (comparing (V.length . b_seq)) x+    nice_sort x = sortBy (comparing (V.length . b_seq . snd)) x      mapGroups f o = tryHead >>= maybe (return o) (\a -> eneeCheckIfDone (mg1 f a []) o)     mg1 f a acc k = tryHead >>= \mb -> case mb of@@ -123,11 +123,11 @@                         Just b | same_pos a b -> mg1 f a (b:acc) k                                | otherwise -> eneeCheckIfDone (mg1 f b []) . k . Chunk . f $ a:acc -check_sort :: Monad m => String -> Enumeratee [BamRec] [BamRec] m a-check_sort msg out = tryHead >>= maybe (return out) (\a -> eneeCheckIfDone (step a) out)+check_sort :: Monad m => (a -> BamRec) -> String -> Enumeratee [a] [a] m b+check_sort f msg out = tryHead >>= maybe (return out) (\a -> eneeCheckIfDone (step a) out)   where     step a k = tryHead >>= maybe (return . k $ Chunk [a]) (step' a k)-    step' a k b | (b_rname a, b_pos a) > (b_rname b, b_pos b) = fail $ "rmdup: " ++ msg+    step' a k b | (b_rname (f a), b_pos (f a)) > (b_rname (f b), b_pos (f b)) = fail $ "rmdup: " ++ msg                 | otherwise = eneeCheckIfDone (step b) . k $ Chunk [a]  @@ -192,15 +192,15 @@    (4) See 'merge_singles' for how it's actually done. -} -do_rmdup :: Ord l => (BamRec -> l) -> Bool -> Collapse -> [BamRec] -> [BamRec]+do_rmdup :: Ord l => (BamRec -> l) -> Bool -> Collapse -> [BamRec] -> [(Int,BamRec)] do_rmdup label strand_preserved Collapse{..} =     concatMap do_rmdup1 . M.elems . accumMap label id   where-    do_rmdup1 rds = results ++ originals (leftovers ++ r1 ++ r2 ++ r3)+    do_rmdup1 rds = results ++ map ((,) 0) (originals (leftovers ++ r1 ++ r2 ++ r3))       where         (results, leftovers) = merge_singles singles' unaligned' $-                [ (str, fromDecision b) | ((_,str  ),b) <- M.toList merged' ] ++-                [ (str, fromDecision b) | ((_,str,_),b) <- M.toList pairs' ]+                [ (str, second fromDecision b) | ((_,str  ),b) <- M.toList merged' ] +++                [ (str, second fromDecision b) | ((_,str,_),b) <- M.toList pairs' ]          (raw_pairs, raw_singles)       = partition isPaired rds         (merged, true_singles)         = partition (liftA2 (||) isMerged isTrimmed) raw_singles@@ -208,8 +208,9 @@         (pairs, raw_half_pairs)        = partition b_totally_aligned raw_pairs         (half_unaligned, half_aligned) = partition isUnmapped raw_half_pairs -        mkMap f x = let m1 = M.map collapse $ accumMap f id x-                    in (M.map fst m1, concatMap snd $ M.elems m1)+        mkMap :: Ord a => (BamRec -> a) -> [BamRec] -> (M.Map a (Int,Decision), [BamRec])+        mkMap f x = let m1 = M.map (\xs -> (length xs, collapse xs)) $ accumMap f id x+                    in (M.map (second fst) m1, concatMap (snd.snd) $ M.elems m1)          (pairs',r1)   = mkMap (\b -> (b_mate_pos b,   b_strand b, b_mate b)) pairs         (merged',r2)  = mkMap (\b -> (alignedLength (b_cigar b), b_strand b))           merged@@ -237,10 +238,10 @@ -- everything(?).  Then we don't have a mate for the consensus... though -- we could decide to duplicate one mate read to get it. -merge_singles :: M.Map Bool Decision                    -- strand --> true singles & half aligned+merge_singles :: M.Map Bool (Int,Decision)              -- strand --> true singles & half aligned               -> M.Map Bool [BamRec]                    -- strand --> half unaligned-              -> [ (Bool, BamRec) ]                     -- strand --> paireds & mergeds-              -> ([BamRec],[BamRec])                    -- results, leftovers+              -> [ (Bool, (Int, BamRec)) ]              -- strand --> paireds & mergeds+              -> ([(Int,BamRec)],[BamRec])              -- results, leftovers  merge_singles singles unaligneds = go   where@@ -250,14 +251,14 @@     -- representative, we add in its XP field and put it into the     -- leftovers.  If there is unaligned stuff here that has the same     -- strand, it goes to the leftovers.-    go ( (str, v) : paireds) =+    go ( (str, (m,v)) : paireds) =         let (r,l) = merge_singles (M.delete str singles) (M.delete str unaligneds) paireds             unal  = M.findWithDefault [] str unaligneds ++ l          in case M.lookup str singles of-            Nothing                 -> (             v : r,     unal )-            Just (Consensus      w) -> ( add_xp_of w v : r,     unal )      -- XXX do we need this w?!-            Just (Representative w) -> ( add_xp_of w v : r, w : unal )+            Nothing                    -> (              (m,v) : r,     unal )+            Just (n, Consensus      w) -> ( (n, add_xp_of w v) : r,     unal )      -- XXX do we need this w?!+            Just (n, Representative w) -> ( (n, add_xp_of w v) : r, w : unal )      -- No more pairs, delegate the problem     go [] = merge_halves unaligneds (M.toList singles)@@ -280,17 +281,16 @@ -- singleton.  merge_halves :: M.Map Bool [BamRec]                     -- strand --> half unaligned-             -> [(Bool, Decision)]                      -- strand --> true singles & half aligned-             -> ([BamRec],[BamRec])                     -- results, leftovers+             -> [(Bool, (Int,Decision))]                -- strand --> true singles & half aligned+             -> ([(Int,BamRec)],[BamRec])               -- results, leftovers  -- Emitting a consensus: make it a single.  Nothing goes to leftovers; -- we may still need it for something else to be emitted.  (While that -- would be strange, making sure the BAM file stays completely valid is -- probably better.)-merge_halves unaligneds ((_, Consensus v) : singles) =-    case merge_halves unaligneds singles of-        (l,r) -> ( v { b_flag = b_flag v .&. complement pflags } : r, l )+merge_halves unaligneds ((_, (n, Consensus v)) : singles) = ( (n, v { b_flag = b_flag v .&. complement pflags }) : r, l )   where+    (r,l)  = merge_halves unaligneds singles     pflags = flagPaired .|. flagProperlyPaired .|. flagMateUnmapped .|. flagMateReversed .|. flagFirstMate .|. flagSecondMate  @@ -299,7 +299,7 @@ -- result.  Everything else goes to leftovers.  If the representative -- happens to be unpaired, no mate is found and that case therefore is -- handled smoothly.-merge_halves unaligneds ((str, Representative v) : singles) = (v : take 1 same ++ r, drop 1 same ++ diff ++ l)+merge_halves unaligneds ((str, (n, Representative v)) : singles) = ((n,v) : map ((,)1) (take 1 same) ++ r, drop 1 same ++ diff ++ l)   where     (r,l)          = merge_halves (M.delete str unaligneds) singles     (same,diff)    = partition (is_mate_of v) $ M.findWithDefault [] str unaligneds
src/Bio/Bam/Trim.hs view
@@ -1,7 +1,21 @@ -- | Trimming of reads as found in BAM files.  Implements trimming low -- quality sequence from the 3' end. -module Bio.Bam.Trim where+module Bio.Bam.Trim+        ( trim_3+        , trim_3'+        , trim_low_quality+        , default_fwd_adapters+        , default_rev_adapters+        , find_merge+        , mergeBam+        , find_trim+        , trimBam+        , mergeTrimBam+        , twoMins+        , merged_seq+        , merged_qual+        ) where  import Bio.Bam.Header import Bio.Bam.Rec@@ -10,7 +24,6 @@ import Bio.Prelude  import Foreign.C.Types      ( CInt(..) )-import Foreign.Ptr          ( Ptr )  import qualified Data.ByteString                        as B import qualified Data.Vector.Generic                    as V@@ -145,6 +158,19 @@ trim_low_quality q = const $ all (< q)  +-- | Finds the merge point.  Input is list of forward adapters, list of+-- reverse adapters, sequence1, quality1, sequence2, quality2; output is+-- merge point and two qualities (YM, YN).+find_merge :: [W.Vector Nucleotides] -> [W.Vector Nucleotides]+           -> W.Vector Nucleotides -> W.Vector Qual+           -> W.Vector Nucleotides -> W.Vector Qual+           -> (Int, Int, Int)+find_merge ads1 ads2 r1 q1 r2 q2 = (mlen, score2 - score1, plain_score - score1)+  where+    plain_score = 6 * fromIntegral (V.length r1 + V.length r2)+    (score1, mlen, score2) = twoMins plain_score (V.length r1 + V.length r2) $+                             merge_score ads1 ads2 r1 q1 r2 q2+ -- | Overlap-merging of read pairs.  We shall compute the likelihood -- for every possible overlap, then select the most likely one (unless it -- looks completely random), compute a quality from the second best@@ -164,16 +190,15 @@ -- would further limit the returned quality!  (In practice, map quality -- later imposes a limit anyway, so no worries...) -merge_overlap :: BamRec -> [ W.Vector Nucleotides ]-              -> BamRec -> [ W.Vector Nucleotides ]-              -> Maybe ( BamRec, BamRec, BamRec, Int, Int )-merge_overlap r1 ads1 r2 ads2-    | V.null (b_seq r1) && V.null (b_seq r2) = Nothing-    | otherwise                              = result mlen score1 score2+mergeBam :: Int -> Int -> [W.Vector Nucleotides] -> [W.Vector Nucleotides] -> BamRec -> BamRec -> [BamRec]+mergeBam lowq highq ads1 ads2 r1 r2+    | V.null (b_seq r1) && V.null (b_seq r2) = [ r1', r2'     ]+    | qual1 < lowq                           = [ r1', r2'     ]+    | qual1 >= highq && mlen == 0            = [              ]+    | qual1 >= highq                         = [           rm ]+    | mlen < len_r1-20 || mlen < len_r2-20   = [           rm ]+    | otherwise         = map flag_alternative [ r1', r2', rm ]   where-    -- the "merge" score if there is no overlap-    plain_score = 6 * fromIntegral (len_r1 + len_r2)-     len_r1    = V.length  $ b_seq  r1     len_r2    = V.length  $ b_seq  r2 @@ -182,84 +207,96 @@     b_qual_r1 = V.convert $ b_qual r1     b_qual_r2 = V.convert $ b_qual r2 -    (score1, mlen, score2) = twoMins plain_score (len_r1 + len_r2) $-                             merge_score ads1 ads2 b_seq_r1 b_qual_r1 b_seq_r2 b_qual_r2+    (mlen, qual1, qual2) = find_merge ads1 ads2 b_seq_r1 b_qual_r1 b_seq_r2 b_qual_r2 -    flag_vestigial    br = br { b_exts = updateE "FF" (Int $ extAsInt 0 "FF" br .|. eflagVestigial) $ b_exts br }-    store_quals s1 s2 br = br { b_exts = updateE "YM" (Int $ s2          - s1) $-                                         updateE "YN" (Int $ plain_score - s1) $ b_exts br }+    flag_alternative br = br { b_exts = updateE "FF" (Int $ extAsInt 0 "FF" br .|. eflagAlternative) $ b_exts br }+    store_quals      br = br { b_exts = updateE "YM" (Int qual1) $ updateE "YN" (Int qual2) $ b_exts br }+    pair_flags = flagPaired.|.flagProperlyPaired.|.flagMateUnmapped.|.flagMateReversed.|.flagFirstMate.|.flagSecondMate -    result l s1 s2 = Just ( store_quals s1 s2 $ flag_vestigial r1-                          , store_quals s1 s2 $ flag_vestigial r2-                          , store_quals s1 s2 $ merged_read l (fromIntegral . min 63 $ s2-s1)-                          , s2 - s1, plain_score - s1 )+    r1' = store_quals r1+    r2' = store_quals r2+    rm  = store_quals $ merged_read mlen (fromIntegral $ min 63 qual1) -    merged_read l qmax-        | V.length merged_seq /= l = error $ "Logic error in merged_read: " ++ show (V.length merged_seq, l)-        | otherwise = nullBamRec {+    merged_read l qmax = nullBamRec {                 b_qname = b_qname r1,                 b_flag  = flagUnmapped .|. complement pair_flags .&. b_flag r1,-                b_seq   = merged_seq,-                b_qual  = merged_qual,+                b_seq   = V.convert $ merged_seq l b_seq_r1 b_qual_r1 b_seq_r2 b_qual_r2,+                b_qual  = V.convert $ merged_qual qmax l b_seq_r1 b_qual_r1 b_seq_r2 b_qual_r2,                 b_exts  = let ff = if l < len_r1 then eflagTrimmed else 0                           in updateE "FF" (Int $ extAsInt 0 "FF" r1 .|. eflagMerged .|. ff) $ b_exts r1 }-      where-        merged_seq = V.convert $ V.concat-                [ V.take (l - len_r2) (b_seq_r1)-                , merge_seqs             (V.take l $ V.drop (l - len_r2) b_seq_r1)-                                         (V.take l $ V.drop (l - len_r2) b_qual_r1)-                             (V.reverse $ V.take l $ V.drop (l - len_r1) b_seq_r2)-                             (V.reverse $ V.take l $ V.drop (l - len_r1) b_qual_r2)-                , V.reverse $ V.take (l - len_r1) b_seq_r2 ] -        merged_qual = V.convert $ V.concat-                [ V.take (l - len_r2) (b_qual_r1)-                , merge_quals qmax        (V.take l $ V.drop (l - len_r2) b_seq_r1)-                                          (V.take l $ V.drop (l - len_r2) b_qual_r1)-                              (V.reverse $ V.take l $ V.drop (l - len_r1) b_seq_r2)-                              (V.reverse $ V.take l $ V.drop (l - len_r1) b_qual_r2)-                , V.reverse $ V.take (l - len_r1) b_qual_r2 ]+{-# INLINE merged_seq #-}+merged_seq :: (V.Vector v Nucleotides, V.Vector v Qual)+           => Int -> v Nucleotides -> v Qual -> v Nucleotides -> v Qual -> v Nucleotides+merged_seq l b_seq_r1 b_qual_r1 b_seq_r2 b_qual_r2 = V.concat+        [ V.take (l - len_r2) (b_seq_r1)+        , V.zipWith4 zz          (V.take l $ V.drop (l - len_r2) b_seq_r1)+                                 (V.take l $ V.drop (l - len_r2) b_qual_r1)+                     (V.reverse $ V.take l $ V.drop (l - len_r1) b_seq_r2)+                     (V.reverse $ V.take l $ V.drop (l - len_r1) b_qual_r2)+        , V.reverse $ V.take (l - len_r1) b_seq_r2 ]+  where+    len_r1 = V.length b_qual_r1+    len_r2 = V.length b_qual_r2+    zz !n1 (Q !q1) !n2 (Q !q2) | n1 == compls n2 =        n1+                               | q1 > q2         =        n1+                               | otherwise       = compls n2 -    pair_flags = flagPaired.|.flagProperlyPaired.|.flagMateUnmapped.|.flagMateReversed.|.flagFirstMate.|.flagSecondMate+{-# INLINE merged_qual #-}+merged_qual :: (V.Vector v Nucleotides, V.Vector v Qual)+            => Word8 -> Int -> v Nucleotides -> v Qual -> v Nucleotides -> v Qual -> v Qual+merged_qual qmax l b_seq_r1 b_qual_r1 b_seq_r2 b_qual_r2 = V.concat+        [ V.take (l - len_r2) (b_qual_r1)+        , V.zipWith4 zz           (V.take l $ V.drop (l - len_r2) b_seq_r1)+                                  (V.take l $ V.drop (l - len_r2) b_qual_r1)+                      (V.reverse $ V.take l $ V.drop (l - len_r1) b_seq_r2)+                      (V.reverse $ V.take l $ V.drop (l - len_r1) b_qual_r2)+        , V.reverse $ V.take (l - len_r1) b_qual_r2 ]+  where+    len_r1 = V.length b_qual_r1+    len_r2 = V.length b_qual_r2+    zz !n1 (Q !q1) !n2 (Q !q2) | n1 == compls n2 = Q $ min qmax (q1 + q2)+                               | q1 > q2         = Q $           q1 - q2+                               | otherwise       = Q $           q2 - q1 -    merge_seqs v1 v2 v3 v4 = V.zipWith4 zz v1 v2 v3 v4-      where-        zz !n1 (Q !q1) !n2 (Q !q2) | n1 == compls n2 =        n1-                                   | q1 > q2         =        n1-                                   | otherwise       = compls n2 -    merge_quals qmax v1 v2 v3 v4 = V.zipWith4 zz v1 v2 v3 v4-      where-        zz !n1 (Q !q1) !n2 (Q !q2) | n1 == compls n2 = Q $ min qmax (q1 + q2)-                                   | q1 > q2         = Q $           q1 - q2-                                   | otherwise       = Q $           q2 - q1 +-- | Finds the trimming point.  Input is list of forward adapters,+-- sequence, quality; output is trim point and two qualities (YM, YN).+find_trim :: [W.Vector Nucleotides]+          -> W.Vector Nucleotides -> W.Vector Qual+          -> (Int, Int, Int)+find_trim ads1 r1 q1 = (mlen, score2 - score1, plain_score - score1)+  where+    plain_score = 6 * fromIntegral (V.length r1)+    (score1, mlen, score2) = twoMins plain_score (V.length r1) $+                             merge_score ads1 [V.empty] r1 q1 V.empty V.empty+ -- | Trimming for a single read:  we need one adapter only (the one coming -- /after/ the read), here provided as a list of options, and then we -- merge with an empty second read.  Results in up to two reads (the -- original, possibly flagged, and the trimmed one, definitely flagged, -- and two qualities).-trim_adapter :: BamRec -> [ W.Vector Nucleotides ] -> Maybe ( BamRec, BamRec, Int, Int )-trim_adapter r1 ads1-    | V.null (b_seq r1) = Nothing-    | otherwise         = result mlen score1 score2+trimBam :: Int -> Int -> [W.Vector Nucleotides] -> BamRec -> [BamRec]+trimBam lowq highq ads1 r1+    | V.null (b_seq r1)              = [ r1'      ]+    | mlen == 0 && qual1 >= highq    = [          ]+    | qual1 < lowq                   = [ r1'      ]+    | qual1 >= highq                 = [      r1t ]+    | otherwise = map flag_alternative [ r1', r1t ]   where     -- the "merge" score if there is no trimming-    plain_score = 6 * fromIntegral (V.length (b_seq r1))      b_seq_r1 = V.convert $ b_seq r1     b_qual_r1 = V.convert $ b_qual r1 -    (score1, mlen, score2) = twoMins plain_score (V.length (b_seq r1)) $-                             merge_score ads1 [V.empty] b_seq_r1 b_qual_r1 V.empty V.empty+    (mlen, qual1, qual2) = find_trim ads1 b_seq_r1 b_qual_r1 -    flag_vestigial    br = br { b_exts = updateE "FF" (Int $ extAsInt 0 "FF" br .|. eflagVestigial) $ b_exts br }-    store_quals s1 s2 br = br { b_exts = updateE "YM" (Int $ s2          - s1) $-                                         updateE "YN" (Int $ plain_score - s1) $ b_exts br }+    flag_alternative br = br { b_exts = updateE "FF" (Int $ extAsInt 0 "FF" br .|. eflagAlternative) $ b_exts br }+    store_quals      br = br { b_exts = updateE "YM" (Int qual1) $ updateE "YN" (Int qual2) $ b_exts br } -    result l s1 s2 = Just ( store_quals s1 s2 $ flag_vestigial r1-                          , store_quals s1 s2 $ trimmed_read l-                          , s2 - s1, plain_score - s1 )+    r1'  = store_quals r1+    r1t  = store_quals $ trimmed_read mlen      trimmed_read l = nullBamRec {             b_qname = b_qname r1,@@ -391,18 +428,14 @@                   | otherwise -> go m1 i1 m2 i2 (i+1)  -mergeTrimBam :: Monad m => [W.Vector Nucleotides] -> [W.Vector Nucleotides] -> Enumeratee [BamRec] [BamRec] m a-mergeTrimBam fwd_ads rev_ads = convStream go+mergeTrimBam :: Monad m => Int -> Int -> [W.Vector Nucleotides] -> [W.Vector Nucleotides] -> Enumeratee [BamRec] [BamRec] m a+mergeTrimBam lowq highq fwd_ads rev_ads = convStream go   where     go = do r1 <- headStream             if isPaired r1               then tryHead >>= go2 r1-              else case trim_adapter r1 fwd_ads of-                    Nothing                -> return [r1]-                    Just (r1',r1t,_q1,_q2) -> return [r1t,r1']+              else return $ trimBam lowq highq fwd_ads r1      go2 r1  Nothing  = error $ "Lone mate found: " ++ show (b_qname r1)-    go2 r1 (Just r2) = case merge_overlap r1 fwd_ads r2 rev_ads of-                    Nothing                   -> return [r1,r2]-                    Just (r1',r2',rm,_q1,_q2) -> return [rm,r1',r2']+    go2 r1 (Just r2) = return $ mergeBam lowq highq fwd_ads rev_ads r1 r2 
src/Bio/Bam/Writer.hs view
@@ -19,7 +19,6 @@ import Data.ByteString.Internal     ( ByteString(..) ) import Data.ByteString.Lazy         ( foldrChunks ) import Foreign.Marshal.Alloc        ( alloca )-import Foreign.Storable             ( pokeByteOff, peek ) import System.IO                    ( openBinaryFile, IOMode(..) )  import qualified Control.Monad.Catch                as C@@ -50,11 +49,12 @@     shows (b_flag b .&. 0xffff),     unpck (sq_name $ getRef refs $ b_rname b),     shows (b_pos b + 1),-    shows (b_mapq b),-    shows (b_cigar b),-    unpck (sq_name $ getRef refs $ b_mrnm b),+    shows (unQ $ b_mapq b),+    V.foldr ((.) . shows) id (b_cigar b),+    if isValidRefseq (b_mrnm b) && b_mrnm b == b_rname b+      then (:) '=' else unpck (sq_name $ getRef refs $ b_mrnm b),     shows (b_mpos b + 1),-    shows (b_isize b + 1),+    shows (b_isize b),     shows (V.toList $ b_seq b),     (++)  (V.toList . V.map (chr . (+33) . fromIntegral . unQ) $ b_qual b) ] .     foldr (\(k,v) f -> (:) '\t' . shows k . (:) ':' . extToSam v . f) id (b_exts b)
src/Bio/Iteratee.hs view
@@ -15,7 +15,6 @@     progressPos,      ($==),-    ListLike,     MonadIO, MonadMask,     lift, liftIO,     stdin, stdout, stderr,@@ -46,20 +45,18 @@     Fd,     withFileFd, -    module Bio.Iteratee.Binary,-    module Bio.Iteratee.Char,+    module Bio.Iteratee.Bytes,     module Bio.Iteratee.IO,     module Bio.Iteratee.Iteratee,-    module Bio.Iteratee.ListLike+    module Bio.Iteratee.List         ) where  import Bio.Bam.Header import Bio.Iteratee.Base-import Bio.Iteratee.Binary-import Bio.Iteratee.Char+import Bio.Iteratee.Bytes import Bio.Iteratee.IO import Bio.Iteratee.Iteratee-import Bio.Iteratee.ListLike+import Bio.Iteratee.List import Bio.Prelude import Bio.Util.Numeric                     ( showNum ) import Control.Concurrent.Async             ( Async, async, wait, cancel )@@ -67,13 +64,11 @@ import Control.Monad.IO.Class import Control.Monad.Trans.Class import Data.Binary.Get-import Data.ListLike                        ( ListLike ) import System.IO                            ( hIsTerminalDevice )  import qualified Control.Monad.Catch            as CMC import qualified Data.Attoparsec.ByteString     as A import qualified Data.ByteString.Char8          as S-import qualified Data.ListLike                  as LL import qualified Data.Vector.Generic            as VG import qualified Data.Vector.Generic.Mutable    as VM @@ -166,17 +161,17 @@  data Ordering' a = Less | Equal a | NotLess -mergeSortStreams :: (Monad m, ListLike s a, Nullable s) => (a -> a -> Ordering' a) -> Enumeratee s s (Iteratee s m) b+mergeSortStreams :: Monad m => (a -> a -> Ordering' a) -> Enumeratee [a] [a] (Iteratee [a] m) b mergeSortStreams comp = eneeCheckIfDone step   where     step out = peekStream >>= \mx -> lift peekStream >>= \my -> case (mx, my) of         (Just x, Just y) -> case x `comp` y of-            Less    -> do dropStream 1 ;                       eneeCheckIfDone step . out . Chunk $ LL.singleton x-            NotLess -> do                lift (dropStream 1) ; eneeCheckIfDone step . out . Chunk $ LL.singleton y-            Equal z -> do dropStream 1 ; lift (dropStream 1) ; eneeCheckIfDone step . out . Chunk $ LL.singleton z+            Less    -> do dropStream 1 ;                       eneeCheckIfDone step . out $ Chunk [x]+            NotLess -> do                lift (dropStream 1) ; eneeCheckIfDone step . out $ Chunk [y]+            Equal z -> do dropStream 1 ; lift (dropStream 1) ; eneeCheckIfDone step . out $ Chunk [z] -        (Just  x, Nothing) -> do       dropStream 1  ; eneeCheckIfDone step . out . Chunk $ LL.singleton x-        (Nothing, Just  y) -> do lift (dropStream 1) ; eneeCheckIfDone step . out . Chunk $ LL.singleton y+        (Just  x, Nothing) -> do       dropStream 1  ; eneeCheckIfDone step . out $ Chunk [x]+        (Nothing, Just  y) -> do lift (dropStream 1) ; eneeCheckIfDone step . out $ Chunk [y]         (Nothing, Nothing) -> idone (liftI out) $ EOF Nothing  @@ -239,28 +234,28 @@  -- | A general progress indicator that prints some message after a set -- number of records have passed through.-progressGen :: (MonadIO m, NullPoint s, ListLike s a)-            => (Int -> a -> String) -> Int -> (String -> IO ()) -> Enumeratee s s m b+progressGen :: MonadIO m+            => (Int -> a -> String) -> Int -> (String -> IO ()) -> Enumeratee [a] [a] m b progressGen msg sz put = eneeCheckIfDonePass (icont . go 0)   where     go !_ k (EOF   mx) = idone (liftI k) (EOF mx)     go !n k (Chunk as)-        | LL.null as = liftI $ go n k-        | otherwise  = let !n' = n + LL.length as+        | null as    = liftI $ go n k+        | otherwise  = let !n' = n + length as                        in when (n' `div` sz /= n `div` sz) (liftIO . put $-                                "\27[K" ++ msg n' (LL.head as) ++ "\r")+                                "\27[K" ++ msg n' (head as) ++ "\r")                           `ioBind_` eneeCheckIfDonePass (icont . go n') (k $ Chunk as)  -- | A simple progress indicator that prints the number of records.-progressNum :: (MonadIO m, NullPoint s, ListLike s a)-            => String -> Int -> (String -> IO ()) -> Enumeratee s s m b+progressNum :: MonadIO m+            => String -> Int -> (String -> IO ()) -> Enumeratee [a] [a] m b progressNum msg = progressGen (\n _ -> msg ++ " " ++ showNum n)  -- | A simple progress indicator that prints a position every set number -- of passed records.-progressPos :: (MonadIO m, ListLike s a, NullPoint s)+progressPos :: MonadIO m             => (a -> (Refseq, Int)) -> String -> Refs-            -> Int -> (String -> IO ()) -> Enumeratee s s m b+            -> Int -> (String -> IO ()) -> Enumeratee [a] [a] m b progressPos f msg refs =     progressGen $ \_ a -> let (!rs1, !po1) = f a                               !nm = unpack . sq_name $ getRef refs rs1@@ -317,7 +312,7 @@  -- | Equivalent to @joinI $ takeStream n $ stream2vector@, but more -- efficient.-stream2vectorN :: (MonadIO m, ListLike s a, Nullable s, VG.Vector v a) => Int -> Iteratee s m (v a)+stream2vectorN :: (MonadIO m, VG.Vector v a) => Int -> Iteratee [a] m (v a) stream2vectorN n = do     mv <- liftIO $ VM.new n     l <- go mv 0@@ -331,7 +326,7 @@                 Just  a -> liftIO (VM.write mv i a) >> go mv (i+1)  -- | Reads the whole stream into a 'VG.Vector'.-stream2vector :: (MonadIO m, ListLike s a, Nullable s, VG.Vector v a) => Iteratee s m (v a)+stream2vector :: (MonadIO m, VG.Vector v a) => Iteratee [a] m (v a) stream2vector = liftIO (VM.new 1024) >>= go 0   where     go !i !mv = tryHead >>= \x -> case x of
src/Bio/Iteratee/Bgzf.hsc view
@@ -122,24 +122,25 @@ -- | Decodes a BGZF block header and returns the block size if -- successful. get_bgzf_header :: Monad m => Iteratee Bytes m (Word16, Word16)-get_bgzf_header = do n <- heads "\31\139"-                     _cm <- headStream-                     flg <- headStream+get_bgzf_header = do x   <- headStreamBS+                     y   <- headStreamBS+                     _cm <- headStreamBS+                     flg <- headStreamBS                      if flg `testBit` 2 then do-                         dropStream 6+                         dropStreamBS 6                          xlen <- endianRead2 LSB-                         it <- takeStream (fromIntegral xlen) get_bsize >>= lift . tryRun+                         it <- takeStreamBS (fromIntegral xlen) get_bsize >>= lift . tryRun                          case it of Left e -> throwErr e-                                    Right s | n == 2 -> return (s,xlen)+                                    Right s | x == 31 && y == 139 -> return (s,xlen)                                     _ -> throwErr $ iterStrExc "No BGZF"                       else throwErr $ iterStrExc "No BGZF"   where-    get_bsize = do i1 <- headStream-                   i2 <- headStream+    get_bsize = do i1 <- headStreamBS+                   i2 <- headStreamBS                    len <- endianRead2 LSB                    if i1 == 66 && i2 == 67 && len == 2                       then endianRead2 LSB-                      else dropStream (fromIntegral len) >> get_bsize+                      else dropStreamBS (fromIntegral len) >> get_bsize  -- | Tests whether a stream is in BGZF format.  Does not consume any -- input.@@ -151,10 +152,11 @@ isGzip :: Monad m => Iteratee Bytes m Bool isGzip = liftM (either (const False) id) $ checkErr $ iLookAhead $ test   where-    test = do n <- heads "\31\139"-              dropStream 24+    test = do x   <- headStreamBS+              y   <- headStreamBS+              dropStreamBS 24               b <- isFinished-              return $ not b && n == 2+              return $ not b && x == 31 && y == 139  -- ------------------------------------------------------------------------- Output 
− src/Bio/Iteratee/Binary.hs
@@ -1,199 +0,0 @@-{-# LANGUAGE FlexibleContexts, BangPatterns #-}---- |Monadic Iteratees:--- incremental input parsers, processors, and transformers------ Iteratees for parsing binary data.--module Bio.Iteratee.Binary (-  -- * Types-  Endian (..)-  -- * Endian multi-byte iteratees-  ,endianRead2-  ,endianRead3-  ,endianRead3i-  ,endianRead4-  ,endianRead8-  -- ** bytestring specializations-  -- | In current versions of @iteratee@ there is no difference between the-  -- bytestring specializations and polymorphic functions.  They exist-  -- for compatibility.-  ,readWord16be_bs-  ,readWord16le_bs-  ,readWord32be_bs-  ,readWord32le_bs-  ,readWord64be_bs-  ,readWord64le_bs-)-where--import Bio.Iteratee.Base-import Data.Bits-import Data.Int-import Data.Word-import Prelude--import qualified Bio.Iteratee.ListLike as I-import qualified Data.ByteString       as B-import qualified Data.ListLike         as LL---- --------------------------------------------------------------------------- Binary Random IO Iteratees---- Iteratees to read unsigned integers written in Big- or Little-endian ways---- | Indicate endian-ness.-data Endian = MSB -- ^ Most Significant Byte is first (big-endian)-  | LSB           -- ^ Least Significan Byte is first (little-endian)-  deriving (Eq, Ord, Show, Enum)--endianRead2-  :: LL.ListLike s Word8-  => Endian-  -> Iteratee s m Word16-endianRead2 e = endianReadN e 2 word16'-{-# INLINE endianRead2 #-}--endianRead3-  :: LL.ListLike s Word8-  => Endian-  -> Iteratee s m Word32-endianRead3 e = endianReadN e 3 (word32' . (0:))-{-# INLINE endianRead3 #-}---- |Read 3 bytes in an endian manner.  If the first bit is set (negative),--- set the entire first byte so the Int32 will be negative as--- well.-endianRead3i-  :: (Nullable s, LL.ListLike s Word8, Monad m)-  => Endian-  -> Iteratee s m Int32-endianRead3i e = do-  c1 <- I.headStream-  c2 <- I.headStream-  c3 <- I.headStream-  case e of-    MSB -> return $ (((fromIntegral c1-                        `shiftL` 8) .|. fromIntegral c2)-                        `shiftL` 8) .|. fromIntegral c3-    LSB ->-     let m :: Int32-         m = shiftR (shiftL (fromIntegral c3) 24) 8-     in return $ (((fromIntegral c3-                        `shiftL` 8) .|. fromIntegral c2)-                        `shiftL` 8) .|. fromIntegral m-{-# INLINE endianRead3i #-}--endianRead4-  :: LL.ListLike s Word8-  => Endian-  -> Iteratee s m Word32-endianRead4 e = endianReadN e 4 word32'-{-# INLINE endianRead4 #-}--endianRead8-  :: LL.ListLike s Word8-  => Endian-  -> Iteratee s m Word64-endianRead8 e = endianReadN e 8 word64'-{-# INLINE endianRead8 #-}---- This function does all the parsing work, depending upon provided arguments-endianReadN ::-  LL.ListLike s Word8-  => Endian-  -> Int-  -> ([Word8] -> b)-  -> Iteratee s m b-endianReadN MSB n0 cnct = liftI (step n0 [])- where-  step !n acc (Chunk c)-    | LL.null c        = liftI (step n acc)-    | LL.length c >= n = let (this,next) = LL.splitAt n c-                             !result     = cnct $ acc ++ LL.toList this-                         in idone result (Chunk next)-    | otherwise        = liftI (step (n - LL.length c) (acc ++ LL.toList c))-  step !n acc (EOF Nothing)  = icont (step n acc) (Just $ toException EofException)-  step !n acc (EOF (Just e)) = icont (step n acc) (Just e)-endianReadN LSB n0 cnct = liftI (step n0 [])- where-  step !n acc (Chunk c)-    | LL.null c        = liftI (step n acc)-    | LL.length c >= n = let (this,next) = LL.splitAt n c-                             !result = cnct $ reverse (LL.toList this) ++ acc-                         in idone result (Chunk next)-    | otherwise        = liftI (step (n - LL.length c)-                                     (reverse (LL.toList c) ++ acc))-  step !n acc (EOF Nothing)  = icont (step n acc)-                                    (Just $ toException EofException)-  step !n acc (EOF (Just e)) = icont (step n acc) (Just e)-{-# INLINE endianReadN #-}---- As of now, the polymorphic code is as fast as the best specializations--- I have found, so these just call out.  They may be improved in the--- future, or possibly deprecated.--- JWL, 2012-01-16--readWord16be_bs :: Iteratee B.ByteString m Word16-readWord16be_bs = endianRead2 MSB-{-# INLINE readWord16be_bs  #-}--readWord16le_bs :: Iteratee B.ByteString m Word16-readWord16le_bs = endianRead2 LSB-{-# INLINE readWord16le_bs  #-}--readWord32be_bs :: Iteratee B.ByteString m Word32-readWord32be_bs = endianRead4 MSB-{-# INLINE readWord32be_bs  #-}--readWord32le_bs :: Iteratee B.ByteString m Word32-readWord32le_bs = endianRead4 LSB-{-# INLINE readWord32le_bs  #-}--readWord64be_bs :: Iteratee B.ByteString m Word64-readWord64be_bs = endianRead8 MSB-{-# INLINE readWord64be_bs  #-}--readWord64le_bs :: Iteratee B.ByteString m Word64-readWord64le_bs = endianRead8 LSB-{-# INLINE readWord64le_bs  #-}--word16' :: [Word8] -> Word16-word16' [c1,c2] = word16 c1 c2-word16' _ = error "iteratee: internal error in word16'"--word16 :: Word8 -> Word8 -> Word16-word16 c1 c2 = (fromIntegral c1 `shiftL`  8) .|.  fromIntegral c2-{-# INLINE word16 #-}--word32' :: [Word8] -> Word32-word32' [c1,c2,c3,c4] = word32 c1 c2 c3 c4-word32' _ = error "iteratee: internal error in word32'"--word32 :: Word8 -> Word8 -> Word8 -> Word8 -> Word32-word32 c1 c2 c3 c4 =-  (fromIntegral c1 `shiftL` 24) .|.-  (fromIntegral c2 `shiftL` 16) .|.-  (fromIntegral c3 `shiftL`  8) .|.-   fromIntegral c4-{-# INLINE word32 #-}--word64' :: [Word8] -> Word64-word64' [c1,c2,c3,c4,c5,c6,c7,c8] = word64 c1 c2 c3 c4 c5 c6 c7 c8-word64' _ = error "iteratee: internal error in word64'"-{-# INLINE word64' #-}--word64-  :: Word8 -> Word8 -> Word8 -> Word8-  -> Word8 -> Word8 -> Word8 -> Word8-  -> Word64-word64 c1 c2 c3 c4 c5 c6 c7 c8 =-  (fromIntegral c1 `shiftL` 56) .|.-  (fromIntegral c2 `shiftL` 48) .|.-  (fromIntegral c3 `shiftL` 40) .|.-  (fromIntegral c4 `shiftL` 32) .|.-  (fromIntegral c5 `shiftL` 24) .|.-  (fromIntegral c6 `shiftL` 16) .|.-  (fromIntegral c7 `shiftL`  8) .|.-   fromIntegral c8-{-# INLINE word64 #-}
src/Bio/Iteratee/Builder.hs view
@@ -24,10 +24,7 @@ import Bio.Iteratee import Bio.Iteratee.Bgzf                   ( compressChunk, maxBlockSize, bgzfEofMarker ) import Bio.Prelude-import Foreign.ForeignPtr                  ( ForeignPtr, withForeignPtr, mallocForeignPtrBytes ) import Foreign.Marshal.Utils               ( copyBytes )-import Foreign.Ptr                         ( Ptr, plusPtr )-import Foreign.Storable                    ( pokeByteOff )  import qualified Data.ByteString            as B import qualified Data.ByteString.Unsafe     as B@@ -75,7 +72,7 @@                 | TkBclSpecial !BclArgs                   BgzfTokens                 | TkLowLevel {-# UNPACK #-} !Int (BB -> IO BB) BgzfTokens -data BclSpecialType = BclNucsBin | BclNucsAsc | BclNucsAscRev | BclQualsBin | BclQualsAsc | BclQualsAscRev+data BclSpecialType = BclNucsBin | BclNucsWide | BclNucsAsc | BclNucsAscRev | BclQualsBin | BclQualsAsc | BclQualsAscRev  data BclArgs = BclArgs BclSpecialType                        {-# UNPACK #-} !(VS.Vector Word8)  -- bcl matrix@@ -238,6 +235,10 @@             nuc_loop p stride (plusPtr q i) u v             return $ (v - u + 2) `div` 2 +        BclNucsWide -> do+            nuc_loop_wide p stride (plusPtr q i) u v+            return $ v - u + 1+         BclNucsAsc -> do             nuc_loop_asc p stride (plusPtr q i) u v             return $ v - u + 1@@ -260,6 +261,9 @@  foreign import ccall unsafe "nuc_loop"     nuc_loop :: Ptr Word8 -> Int -> Ptr Word8 -> Int -> Int -> IO ()++foreign import ccall unsafe "nuc_loop_wide"+    nuc_loop_wide :: Ptr Word8 -> Int -> Ptr Word8 -> Int -> Int -> IO ()  foreign import ccall unsafe "nuc_loop_asc"     nuc_loop_asc :: Ptr Word8 -> Int -> Ptr Word8 -> Int -> Int -> IO ()
+ src/Bio/Iteratee/Bytes.hs view
@@ -0,0 +1,269 @@+{-# LANGUAGE FlexibleContexts, BangPatterns #-}++-- |Monadic Iteratees:+-- incremental input parsers, processors, and transformers+--+-- Iteratees for parsing binary data.++module Bio.Iteratee.Bytes (+  -- * Types+  Endian (..)+  -- * Endian multi-byte iteratees+  ,endianRead2+  ,endianRead3+  ,endianRead3i+  ,endianRead4+  ,endianRead8++  -- * Iteratees treating Bytes as list of Word8+  ,headStreamBS+  ,tryHeadBS+  ,peekStreamBS+  ,takeStreamBS+  ,dropStreamBS+  ,dropWhileStreamBS++  -- * Iteratees treating Bytes as list of Char+  ,enumLinesBS+  ,enumWordsBS+)+where++import Bio.Iteratee.Base+import Bio.Iteratee.Iteratee+import Bio.Prelude++import qualified Data.ByteString              as B+import qualified Data.ByteString.Char8        as C+import qualified Data.ByteString.Unsafe       as B++-- ------------------------------------------------------------------------+-- Binary Random IO Iteratees++-- Iteratees to read unsigned integers written in Big- or Little-endian ways++-- | Indicate endian-ness.+data Endian = MSB -- ^ Most Significant Byte is first (big-endian)+  | LSB           -- ^ Least Significan Byte is first (little-endian)+  deriving (Eq, Ord, Show, Enum)++endianRead2 :: Endian -> Iteratee Bytes m Word16+endianRead2 e = endianReadN e 2 word16'+{-# INLINE endianRead2 #-}++endianRead3 :: Endian -> Iteratee Bytes m Word32+endianRead3 e = endianReadN e 3 (word32' . (0:))+{-# INLINE endianRead3 #-}++-- |Read 3 bytes in an endian manner.  If the first bit is set (negative),+-- set the entire first byte so the Int32 will be negative as+-- well.+endianRead3i :: Monad m => Endian -> Iteratee Bytes m Int32+endianRead3i e = do+  c1 <- headStreamBS+  c2 <- headStreamBS+  c3 <- headStreamBS+  case e of+    MSB -> return $ (((fromIntegral c1+                        `shiftL` 8) .|. fromIntegral c2)+                        `shiftL` 8) .|. fromIntegral c3+    LSB ->+     let m :: Int32+         m = shiftR (shiftL (fromIntegral c3) 24) 8+     in return $ (((fromIntegral c3+                        `shiftL` 8) .|. fromIntegral c2)+                        `shiftL` 8) .|. fromIntegral m+{-# INLINE endianRead3i #-}++endianRead4 :: Endian -> Iteratee Bytes m Word32+endianRead4 e = endianReadN e 4 word32'+{-# INLINE endianRead4 #-}++endianRead8 :: Endian -> Iteratee Bytes m Word64+endianRead8 e = endianReadN e 8 word64'+{-# INLINE endianRead8 #-}++-- This function does all the parsing work, depending upon provided arguments+endianReadN ::+  Endian+  -> Int+  -> ([Word8] -> b)+  -> Iteratee Bytes m b+endianReadN MSB n0 cnct = liftI (step n0 [])+ where+  step !n acc (Chunk c)+    | B.null c        = liftI (step n acc)+    | B.length c >= n = let (this,next) = B.splitAt n c+                            !result     = cnct $ acc ++ B.unpack this+                        in idone result (Chunk next)+    | otherwise        = liftI (step (n - B.length c) (acc ++ B.unpack c))+  step !n acc (EOF Nothing)  = icont (step n acc) (Just $ toException EofException)+  step !n acc (EOF (Just e)) = icont (step n acc) (Just e)+endianReadN LSB n0 cnct = liftI (step n0 [])+ where+  step !n acc (Chunk c)+    | B.null c        = liftI (step n acc)+    | B.length c >= n = let (this,next) = B.splitAt n c+                            !result = cnct $ B.unpack (B.reverse this) ++ acc+                        in idone result (Chunk next)+    | otherwise        = liftI (step (n - B.length c)+                                     (B.unpack (B.reverse c) ++ acc))+  step !n acc (EOF Nothing)  = icont (step n acc)+                                    (Just $ toException EofException)+  step !n acc (EOF (Just e)) = icont (step n acc) (Just e)+{-# INLINE endianReadN #-}+++word16' :: [Word8] -> Word16+word16' [c1,c2] = word16 c1 c2+word16' _ = error "iteratee: internal error in word16'"++word16 :: Word8 -> Word8 -> Word16+word16 c1 c2 = (fromIntegral c1 `shiftL`  8) .|.  fromIntegral c2+{-# INLINE word16 #-}++word32' :: [Word8] -> Word32+word32' [c1,c2,c3,c4] = word32 c1 c2 c3 c4+word32' _ = error "iteratee: internal error in word32'"++word32 :: Word8 -> Word8 -> Word8 -> Word8 -> Word32+word32 c1 c2 c3 c4 =+  (fromIntegral c1 `shiftL` 24) .|.+  (fromIntegral c2 `shiftL` 16) .|.+  (fromIntegral c3 `shiftL`  8) .|.+   fromIntegral c4+{-# INLINE word32 #-}++word64' :: [Word8] -> Word64+word64' [c1,c2,c3,c4,c5,c6,c7,c8] = word64 c1 c2 c3 c4 c5 c6 c7 c8+word64' _ = error "iteratee: internal error in word64'"+{-# INLINE word64' #-}++word64+  :: Word8 -> Word8 -> Word8 -> Word8+  -> Word8 -> Word8 -> Word8 -> Word8+  -> Word64+word64 c1 c2 c3 c4 c5 c6 c7 c8 =+  (fromIntegral c1 `shiftL` 56) .|.+  (fromIntegral c2 `shiftL` 48) .|.+  (fromIntegral c3 `shiftL` 40) .|.+  (fromIntegral c4 `shiftL` 32) .|.+  (fromIntegral c5 `shiftL` 24) .|.+  (fromIntegral c6 `shiftL` 16) .|.+  (fromIntegral c7 `shiftL`  8) .|.+   fromIntegral c8+{-# INLINE word64 #-}++headStreamBS :: Iteratee Bytes m Word8+headStreamBS = liftI step+  where+  step (Chunk c)+    | B.null c = icont step Nothing+    | otherwise  = idone (B.unsafeHead c) (Chunk (B.unsafeTail c))+  step stream          = icont step (Just (setEOF stream))+{-# INLINE headStreamBS #-}++peekStreamBS :: Iteratee Bytes m (Maybe Word8)+peekStreamBS = liftI step+  where+    step s@(Chunk vec)+      | B.null vec = liftI step+      | otherwise   = idone (Just $ B.unsafeHead vec) s+    step stream     = idone Nothing stream+{-# INLINE peekStreamBS #-}++tryHeadBS :: Iteratee Bytes m (Maybe Word8)+tryHeadBS = liftI step+  where+  step (Chunk vec)+    | B.null vec = liftI step+    | otherwise  = idone (Just (B.unsafeHead vec)) (Chunk (B.unsafeTail vec))+  step stream          = idone Nothing stream+{-# INLINE tryHeadBS #-}++dropStreamBS :: Int -> Iteratee Bytes m ()+dropStreamBS 0  = idone () (Chunk emptyP)+dropStreamBS n' = liftI (step n')+  where+    step n (Chunk str)+      | B.length str < n = liftI (step (n - B.length str))+      | otherwise        = idone () (Chunk (B.drop n str))+    step _ stream        = idone () stream+{-# INLINE dropStreamBS #-}++dropWhileStreamBS :: (Word8 -> Bool) -> Iteratee Bytes m ()+dropWhileStreamBS p = liftI step+  where+    step (Chunk str)+      | B.null rest  = liftI step+      | otherwise    = idone () (Chunk rest)+      where+        rest = B.dropWhile p str+    step stream      = idone () stream+{-# INLINE dropWhileStreamBS #-}++takeStreamBS ::+  Monad m+  => Int   -- ^ number of elements to consume+  -> Enumeratee Bytes Bytes m a+takeStreamBS n' iter+ | n' <= 0   = return iter+ | otherwise = Iteratee $ \od oc -> runIter iter (on_done od oc) (on_cont od oc)+  where+    on_done od oc x _ = runIter (dropStreamBS n' >> return (return x)) od oc+    on_cont od oc k Nothing = if n' == 0 then od (liftI k) (Chunk mempty)+                                 else runIter (liftI (step n' k)) od oc+    on_cont od oc _ (Just e) = runIter (dropStreamBS n' >> throwErr e) od oc+    step n k (Chunk str)+      | B.null str        = liftI (step n k)+      | B.length str <= n = takeStreamBS (n - B.length str) $ k (Chunk str)+      | otherwise          = idone (k (Chunk s1)) (Chunk s2)+      where (s1, s2) = B.splitAt n str+    step _n k stream       = idone (liftI k) stream+{-# INLINE takeStreamBS #-}++-- Like enumWords, but operates on ByteStrings.+-- This is provided as a higher-performance alternative to enumWords, and+-- is equivalent to treating the stream as a Data.ByteString.Char8.ByteString.+enumWordsBS :: Monad m => Enumeratee Bytes [Bytes] m a+enumWordsBS iter = convStream getter iter+  where+    getter = liftI step+    lChar = isSpace . C.last+    step (Chunk xs)+      | C.null xs  = getter+      | lChar xs   = idone (C.words xs) (Chunk C.empty)+      | otherwise  = icont (step' xs) Nothing+    step str       = idone mempty str+    step' xs (Chunk ys)+      | C.null ys  = icont (step' xs) Nothing+      | lChar ys   = idone (C.words . C.append xs $ ys) mempty+      | otherwise  = let w' = C.words . C.append xs $ ys+                         ws = init w'+                         ck = last w'+                     in idone ws (Chunk ck)+    step' xs str   = idone (C.words xs) str+{-# INLINE enumWordsBS #-}++-- Like enumLines, but operates on ByteStrings.+-- This is provided as a higher-performance alternative to enumLines, and+-- is equivalent to treating the stream as a Data.ByteString.Char8.ByteString.+enumLinesBS :: Monad m => Enumeratee Bytes [Bytes] m a+enumLinesBS = convStream getter+  where+    getter = icont step Nothing+    lChar = (== '\n') . C.last+    step (Chunk xs)+      | C.null xs  = getter+      | lChar xs   = idone (C.lines xs) (Chunk C.empty)+      | otherwise  = icont (step' xs) Nothing+    step str       = idone mempty str+    step' xs (Chunk ys)+      | C.null ys  = icont (step' xs) Nothing+      | lChar ys   = idone (C.lines . C.append xs $ ys) mempty+      | otherwise  = let w' = C.lines $ C.append xs ys+                         ws = init w'+                         ck = last w'+                     in idone ws (Chunk ck)+    step' xs str   = idone (C.lines xs) str+{-# INLINE enumLinesBS #-}
− src/Bio/Iteratee/Char.hs
@@ -1,151 +0,0 @@-{-# LANGUAGE ScopedTypeVariables, FlexibleContexts #-}---- | Utilities for Char-based iteratee processing.--module Bio.Iteratee.Char (-  -- * Word and Line processors-  printLines-  ,printLinesUnterminated-  ,enumLines-  ,enumLinesBS-  ,enumWords-  ,enumWordsBS-)--where--import           Bio.Iteratee.Iteratee-import           Bio.Iteratee.ListLike-import           Data.Char-import           Data.Monoid-import qualified Data.ListLike as LL-import           Control.Monad (liftM)-import           Control.Monad.IO.Class-import qualified Data.ByteString.Char8 as BC-import           Prelude----- |Print lines as they are received. This is the first `impure' iteratee--- with non-trivial actions during chunk processing------  Only lines ending with a newline are printed,---  data terminated with EOF is not printed.-printLines :: Iteratee String IO ()-printLines = lines'- where-  lines' = breakStream (\c -> c == '\r' || c == '\n') >>= \l -> terminators >>= check l-  check _  0 = return ()-  check "" _ = return ()-  check l  _ = liftIO (putStrLn l) >> lines'---- |Print lines as they are received.------  All lines are printed, including a line with a terminating EOF.---  If the final line is terminated by EOF without a newline,---  no newline is printed.---  this function should be used in preference to printLines when possible,---  as it is more efficient with long lines.-printLinesUnterminated :: forall s el.-                       (Eq el, Nullable s, LL.StringLike s, LL.ListLike s el)-                       => Iteratee s IO ()-printLinesUnterminated = lines'- where-  lines' = do-    joinI $ breakE (`LL.elem` t1) (mapChunksM_ (putStr . LL.toString))-    terminators >>= check-  check 0 = return ()-  check _ = liftIO (putStrLn "") >> lines'-  t1 :: s-  t1 = LL.fromString "\r\n"--terminators :: (Eq el, Nullable s, LL.StringLike s, LL.ListLike s el)-            => Iteratee s IO Int-terminators = do-  l <- heads (LL.fromString "\r\n")-  if l == 0 then heads (LL.fromString "\n") else return l----- |Convert the stream of characters to the stream of lines, and--- apply the given iteratee to enumerate the latter.--- The stream of lines is normally terminated by the empty line.--- When the stream of characters is terminated, the stream of lines--- is also terminated.--- This is the first proper iteratee-enumerator: it is the iteratee of the--- character stream and the enumerator of the line stream.--enumLines-  :: (LL.ListLike s el, LL.StringLike s, Nullable s, Monad m) =>-     Enumeratee s [s] m a-enumLines = convStream getter-  where-    getter = icont step Nothing-    lChar = (== '\n') . last . LL.toString-    step (Chunk xs)-      | LL.null xs = getter-      | lChar xs   = idone (LL.lines xs) mempty-      | otherwise  = icont (step' xs) Nothing-    step _str      = getter-    step' xs (Chunk ys)-      | LL.null ys = icont (step' xs) Nothing-      | lChar ys   = idone (LL.lines . mappend xs $ ys) mempty-      | otherwise  = let w' = LL.lines $ mappend xs ys-                         ws = init w'-                         ck = last w'-                     in idone ws (Chunk ck)-    step' xs str   = idone (LL.lines xs) str---- |Convert the stream of characters to the stream of words, and--- apply the given iteratee to enumerate the latter.--- Words are delimited by white space.--- This is the analogue of List.words-enumWords :: (LL.ListLike s Char, Nullable s, Monad m) => Enumeratee s [s] m a-enumWords = convStream $ dropWhileStream isSpace >> liftM (:[]) (breakStream isSpace)-{-# INLINE enumWords #-}---- Like enumWords, but operates on ByteStrings.--- This is provided as a higher-performance alternative to enumWords, and--- is equivalent to treating the stream as a Data.ByteString.Char8.ByteString.-enumWordsBS-  :: (Monad m) => Enumeratee BC.ByteString [BC.ByteString] m a-enumWordsBS iter = convStream getter iter-  where-    getter = liftI step-    lChar = isSpace . BC.last-    step (Chunk xs)-      | BC.null xs = getter-      | lChar xs   = idone (BC.words xs) (Chunk BC.empty)-      | otherwise  = icont (step' xs) Nothing-    step str       = idone mempty str-    step' xs (Chunk ys)-      | BC.null ys = icont (step' xs) Nothing-      | lChar ys   = idone (BC.words . BC.append xs $ ys) mempty-      | otherwise  = let w' = BC.words . BC.append xs $ ys-                         ws = init w'-                         ck = last w'-                     in idone ws (Chunk ck)-    step' xs str   = idone (BC.words xs) str--{-# INLINE enumWordsBS #-}---- Like enumLines, but operates on ByteStrings.--- This is provided as a higher-performance alternative to enumLines, and--- is equivalent to treating the stream as a Data.ByteString.Char8.ByteString.-enumLinesBS :: (Monad m) => Enumeratee BC.ByteString [BC.ByteString] m a-enumLinesBS = convStream getter-  where-    getter = icont step Nothing-    lChar = (== '\n') . BC.last-    step (Chunk xs)-      | BC.null xs = getter-      | lChar xs   = idone (BC.lines xs) (Chunk BC.empty)-      | otherwise  = icont (step' xs) Nothing-    step str       = idone mempty str-    step' xs (Chunk ys)-      | BC.null ys = icont (step' xs) Nothing-      | lChar ys   = idone (BC.lines . BC.append xs $ ys) mempty-      | otherwise  = let w' = BC.lines $ BC.append xs ys-                         ws = init w'-                         ck = last w'-                     in idone ws (Chunk ck)-    step' xs str   = idone (BC.lines xs) str-
src/Bio/Iteratee/IO.hs view
@@ -26,12 +26,10 @@  where -import Bio.Iteratee.ReadableChunk import Bio.Iteratee.Iteratee-import Bio.Iteratee.Binary ()+import Bio.Prelude import Control.Monad.Catch import Control.Monad.IO.Class-import Prelude  import qualified Bio.Iteratee.IO.Handle as H import qualified Bio.Iteratee.IO.Fd as FD@@ -47,33 +45,33 @@  -- If Posix is available, use the fileDriverRandomFd as fileDriverRandom.  Otherwise, use a handle-based variant. enumFile-  :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) =>+  :: (MonadIO m, MonadMask m) =>      Int      -> FilePath-     -> Enumerator s m a+     -> Enumerator Bytes m a enumFile = FD.enumFile  enumFileRandom-  :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) =>+  :: (MonadIO m, MonadMask m) =>      Int      -> FilePath-     -> Enumerator s m a+     -> Enumerator Bytes m a enumFileRandom = FD.enumFileRandom  -- |Process a file using the given Iteratee.  This function wraps -- enumFd as a convenience. fileDriver-  :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) =>-     Iteratee s m a+  :: (MonadIO m, MonadMask m) =>+     Iteratee Bytes m a      -> FilePath      -> m a fileDriver = FD.fileDriverFd defaultBufSize  -- |A version of fileDriver with a user-specified buffer size (in elements). fileDriverVBuf-  :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) =>+  :: (MonadIO m, MonadMask m) =>      Int-     -> Iteratee s m a+     -> Iteratee Bytes m a      -> FilePath      -> m a fileDriverVBuf = FD.fileDriverFd@@ -81,16 +79,16 @@ -- |Process a file using the given Iteratee.  This function wraps -- enumFdRandom as a convenience. fileDriverRandom-  :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) =>-     Iteratee s m a+  :: (MonadIO m, MonadMask m) =>+     Iteratee Bytes m a      -> FilePath      -> m a fileDriverRandom = FD.fileDriverRandomFd defaultBufSize  fileDriverRandomVBuf-  :: (MonadIO m, MonadMask m, NullPoint s, ReadableChunk s el) =>+  :: (MonadIO m, MonadMask m) =>      Int-     -> Iteratee s m a+     -> Iteratee Bytes m a      -> FilePath      -> m a fileDriverRandomVBuf = FD.fileDriverRandomFd
src/Bio/Iteratee/IO/Fd.hs view
@@ -1,6 +1,3 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ConstraintKinds #-}- -- |Random and Binary IO with generic Iteratees, using File Descriptors for IO. -- when available, these are the preferred functions for performing IO as they -- run in constant space and function properly with sockets, pipes, etc.@@ -20,16 +17,13 @@  where -import Bio.Iteratee.Binary () import Bio.Iteratee.IO.Base import Bio.Iteratee.Iteratee-import Bio.Iteratee.ReadableChunk import Bio.Prelude import Control.Monad.Catch as CIO import Control.Monad.IO.Class+import Data.ByteString (packCStringLen) import Foreign.Marshal.Alloc-import Foreign.Ptr-import Foreign.Storable import System.IO (SeekMode(..))  @@ -37,12 +31,12 @@ -- Binary Random IO enumerators  makefdCallback ::-  (MonadIO m, NullPoint s, ReadableChunk s el) =>+  MonadIO m =>   Ptr el   -> ByteCount   -> Fd   -> st-  -> m (Either SomeException ((Bool, st), s))+  -> m (Either SomeException ((Bool, st), Bytes)) makefdCallback p bufsize fd st = do   n <- liftIO $ myfdRead fd (castPtr p) bufsize   case n of@@ -50,42 +44,42 @@     Right 0  -> liftIO yield >> return (Right ((False, st), emptyP))     Right n' -> liftM (\s -> Right ((True, st), s)) $                   readFromPtr p (fromIntegral n')+  where+    readFromPtr buf l = liftIO $ packCStringLen (castPtr buf, l)  -- |The enumerator of a POSIX File Descriptor.  This version enumerates -- over the entire contents of a file, in order, unless stopped by -- the iteratee.  In particular, seeking is not supported. enumFd-  :: forall s el m a.(NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) =>+  :: (MonadIO m, MonadMask m) =>      Int      -> Fd-     -> Enumerator s m a-enumFd bs fd iter =-  let bufsize = bs * (sizeOf (undefined :: el))-  in CIO.bracket (liftIO $ mallocBytes bufsize)-                 (liftIO . free)-                 (\p -> enumFromCallback (makefdCallback p (fromIntegral bufsize) fd) () iter)+     -> Enumerator Bytes m a+enumFd bufsize fd iter =+  CIO.bracket (liftIO $ mallocBytes bufsize)+              (liftIO . free)+              (\p -> enumFromCallback (makefdCallback p (fromIntegral bufsize) fd) () iter)  -- |A variant of enumFd that catches exceptions raised by the @Iteratee@. enumFdCatch- :: forall e s el m a.(IException e, NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m)+ :: (IException e, MonadIO m, MonadMask m)     => Int     -> Fd     -> (e -> m (Maybe EnumException))-    -> Enumerator s m a-enumFdCatch bs fd handler iter =-  let bufsize = bs * (sizeOf (undefined :: el))-  in CIO.bracket (liftIO $ mallocBytes bufsize)-                 (liftIO . free)-                 (\p -> enumFromCallbackCatch (makefdCallback p (fromIntegral bufsize) fd) handler () iter)+    -> Enumerator Bytes m a+enumFdCatch bufsize fd handler iter =+  CIO.bracket (liftIO $ mallocBytes bufsize)+              (liftIO . free)+              (\p -> enumFromCallbackCatch (makefdCallback p (fromIntegral bufsize) fd) handler () iter)   -- |The enumerator of a POSIX File Descriptor: a variation of @enumFd@ that -- supports RandomIO (seek requests). enumFdRandom- :: forall s el m a.(NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) =>+ :: (MonadIO m, MonadMask m) =>     Int     -> Fd-    -> Enumerator s m a+    -> Enumerator Bytes m a enumFdRandom bs fd iter = enumFdCatch bs fd handler iter   where     handler (SeekException off) =@@ -108,18 +102,18 @@  -- |Process a file using the given @Iteratee@. fileDriverFd-  :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) =>+  :: (MonadIO m, MonadMask m) =>      Int -- ^Buffer size (number of elements)-     -> Iteratee s m a+     -> Iteratee Bytes m a      -> FilePath      -> m a fileDriverFd = fileDriver enumFd  -- |A version of fileDriverFd that supports seeking. fileDriverRandomFd-  :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) =>+  :: (MonadIO m, MonadMask m) =>      Int-     -> Iteratee s m a+     -> Iteratee Bytes m a      -> FilePath      -> m a fileDriverRandomFd = fileDriver enumFdRandom@@ -135,17 +129,17 @@   (flip (enumf bufsize) iter)  enumFile ::-  (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el)+  (MonadIO m, MonadMask m)   => Int                 -- ^Buffer size   -> FilePath-  -> Enumerator s m a+  -> Enumerator Bytes m a enumFile = enumFile' enumFd  enumFileRandom ::-  (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el)+  (MonadIO m, MonadMask m)   => Int                 -- ^Buffer size   -> FilePath-  -> Enumerator s m a+  -> Enumerator Bytes m a enumFileRandom = enumFile' enumFdRandom  
src/Bio/Iteratee/IO/Handle.hs view
@@ -20,27 +20,24 @@  where -import Bio.Iteratee.Binary () import Bio.Iteratee.Iteratee-import Bio.Iteratee.ReadableChunk import Bio.Prelude import Control.Monad.Catch as CIO import Control.Monad.IO.Class+import Data.ByteString (packCStringLen) import Foreign.Marshal.Alloc-import Foreign.Ptr-import Foreign.Storable import System.IO  -- ------------------------------------------------------------------------ -- Binary Random IO enumerators  makeHandleCallback ::-  (MonadIO m, NullPoint s, ReadableChunk s el) =>-  Ptr el+  MonadIO m =>+  Ptr Word8   -> Int   -> Handle   -> st-  -> m (Either SomeException ((Bool, st), s))+  -> m (Either SomeException ((Bool, st), Bytes)) makeHandleCallback p bsize h st = do   n' <- liftIO (CIO.try $ hGetBuf h p bsize :: IO (Either SomeException Int))   case n' of@@ -48,6 +45,8 @@     Right 0 -> return $ Right ((False, st), emptyP)     Right n -> liftM (\s -> Right ((True, st), s)) $                  readFromPtr p (fromIntegral n)+  where+    readFromPtr buf l = liftIO $ packCStringLen (castPtr buf, l)   -- |The (monadic) enumerator of a file Handle.  This version enumerates@@ -55,43 +54,39 @@ -- the iteratee.  In particular, seeking is not supported. -- Data is read into a buffer of the specified size. enumHandle ::- forall s el m a.(NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) =>+  (MonadIO m, MonadMask m) =>   Int -- ^Buffer size (number of elements per read)   -> Handle-  -> Enumerator s m a-enumHandle bs h i =-  let bufsize = bs * sizeOf (undefined :: el)-  in CIO.bracket (liftIO $ mallocBytes bufsize)-                 (liftIO . free)-                 (\p -> enumFromCallback (makeHandleCallback p bufsize h) () i)+  -> Enumerator Bytes m a+enumHandle bufsize h i =+  CIO.bracket (liftIO $ mallocBytes bufsize)+              (liftIO . free)+              (\p -> enumFromCallback (makeHandleCallback p bufsize h) () i)  -- |An enumerator of a file handle that catches exceptions raised by -- the Iteratee. enumHandleCatch  ::- forall e s el m a.(IException e,-                    NullPoint s,-                    ReadableChunk s el,-                    MonadIO m, MonadMask m) =>+ forall e m a.(IException e,+               MonadIO m, MonadMask m) =>   Int -- ^Buffer size (number of elements per read)   -> Handle   -> (e -> m (Maybe EnumException))-  -> Enumerator s m a-enumHandleCatch bs h handler i =-  let bufsize = bs * sizeOf (undefined :: el)-  in CIO.bracket (liftIO $ mallocBytes bufsize)-                 (liftIO . free)-                 (\p -> enumFromCallbackCatch (makeHandleCallback p bufsize h) handler () i)+  -> Enumerator Bytes m a+enumHandleCatch bufsize h handler i =+  CIO.bracket (liftIO $ mallocBytes bufsize)+              (liftIO . free)+              (\p -> enumFromCallbackCatch (makeHandleCallback p bufsize h) handler () i)   -- |The enumerator of a Handle: a variation of enumHandle that -- supports RandomIO (seek requests). -- Data is read into a buffer of the specified size. enumHandleRandom ::- forall s el m a.(NullPoint s, ReadableChunk s el, MonadIO m, MonadMask m) =>+ forall m a.(MonadIO m, MonadMask m) =>   Int -- ^ Buffer size (number of elements per read)   -> Handle-  -> Enumerator s m a+  -> Enumerator Bytes m a enumHandleRandom bs h i = enumHandleCatch bs h handler i   where     handler (SeekException off) =@@ -114,25 +109,25 @@   (flip (enumf bufsize) iter)  enumFile ::-  (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el)+  (MonadIO m, MonadMask m)   => Int                 -- ^Buffer size   -> FilePath-  -> Enumerator s m a+  -> Enumerator Bytes m a enumFile = enumFile' enumHandle  enumFileRandom ::-  (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el)+  (MonadIO m, MonadMask m)   => Int                 -- ^Buffer size   -> FilePath-  -> Enumerator s m a+  -> Enumerator Bytes m a enumFileRandom = enumFile' enumHandleRandom  -- |Process a file using the given @Iteratee@.  This function wraps -- @enumHandle@ as a convenience. fileDriverHandle-  :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) =>+  :: (MonadIO m, MonadMask m) =>      Int                      -- ^Buffer size (number of elements)-     -> Iteratee s m a+     -> Iteratee Bytes m a      -> FilePath      -> m a fileDriverHandle bufsize iter filepath =@@ -140,9 +135,9 @@  -- |A version of @fileDriverHandle@ that supports seeking. fileDriverRandomHandle-  :: (NullPoint s, MonadIO m, MonadMask m, ReadableChunk s el) =>+  :: (MonadIO m, MonadMask m) =>      Int                      -- ^ Buffer size (number of elements)-     -> Iteratee s m a+     -> Iteratee Bytes m a      -> FilePath      -> m a fileDriverRandomHandle bufsize iter filepath =
+ src/Bio/Iteratee/List.hs view
@@ -0,0 +1,815 @@+{-# LANGUAGE TupleSections, ScopedTypeVariables #-}++-- |Monadic Iteratees:+-- incremental input parsers, processors and transformers+--+-- This module provides many basic iteratees from which more complicated+-- iteratees can be built.  In general these iteratees parallel those in+-- @Data.List@, with some additions.++module Bio.Iteratee.List (+  -- * Iteratees+  -- ** Iteratee Utilities+  isFinished+  ,stream2list+  ,stream2stream+  -- ** Basic Iteratees+  ,dropWhileStream+  ,dropStream+  ,headStream+  ,tryHead+  ,lastStream+  ,heads+  ,peekStream+  ,roll+  ,lengthStream+  ,chunkLength+  ,takeFromChunk+  -- ** Nested iteratee combinators+  ,breakStream+  ,breakE+  ,takeStream+  ,takeUpTo+  ,takeWhileE+  ,mapStream+  ,concatMapStream+  ,concatMapStreamM+  ,mapMaybeStream+  ,filterStream+  ,filterStreamM+  ,groupStreamBy+  ,groupStreamOn+  ,mergeStreams+  ,mergeByChunks+  -- ** Folds+  ,foldStream+  -- * Enumerators+  -- ** Basic enumerators+  ,enumPureNChunk+  -- ** Enumerator Combinators+  ,enumWith+  ,zipStreams+  ,zipStreams3+  ,zipStreams4+  ,zipStreams5+  ,sequenceStreams_+  ,countConsumed+  -- ** Monadic functions+  ,mapStreamM+  ,mapStreamM_+  ,foldStreamM+  -- * Re-exported modules+  ,module Bio.Iteratee.Iteratee+)+where++import Bio.Iteratee.Iteratee+import Bio.Prelude+import Control.Monad.Trans.Class++-- import qualified Data.ByteString          as B+++-- Useful combinators for implementing iteratees and enumerators++-- | Check if a stream has received 'EOF'.+isFinished :: Nullable s => Iteratee s m Bool+isFinished = liftI check+  where+  check c@(Chunk xs)+    | nullC xs    = liftI check+    | otherwise   = idone False c+  check s@(EOF _) = idone True s+{-# INLINE isFinished #-}++-- ------------------------------------------------------------------------+-- Primitive iteratees++-- |Read a stream to the end and return all of its elements as a list.+-- This iteratee returns all data from the stream *strictly*.+stream2list :: Monad m => Iteratee [el] m [el]+stream2list = liftM concat getChunks+{-# INLINE stream2list #-}++-- |Read a stream to the end and return all of its elements as a stream.+-- This iteratee returns all data from the stream *strictly*.+stream2stream :: (Monad m, Nullable s, Monoid s) => Iteratee s m s+stream2stream = liftM mconcat getChunks+{-# INLINE stream2stream #-}+++-- ------------------------------------------------------------------------+-- Parser combinators++-- |Attempt to read the next element of the stream and return it+-- Raise a (recoverable) error if the stream is terminated.+--+-- The analogue of @List.head@+--+-- Because @head@ can raise an error, it shouldn't be used when constructing+-- iteratees for @convStream@.  Use @tryHead@ instead.+headStream :: Iteratee [el] m el+headStream = liftI step+  where+  step (Chunk [     ]) = icont step Nothing+  step (Chunk (hd:tl)) = idone hd (Chunk tl)+  step stream          = icont step (Just (setEOF stream))+{-# INLINE headStream #-}++-- | Similar to @headStream@, except it returns @Nothing@ if the stream+-- is terminated.+tryHead :: Iteratee [el] m (Maybe el)+tryHead = liftI step+  where+  step (Chunk [     ]) = liftI step+  step (Chunk (hd:tl)) = idone (Just hd) (Chunk tl)+  step stream          = idone Nothing stream+{-# INLINE tryHead #-}++-- |Attempt to read the last element of the stream and return it+-- Raise a (recoverable) error if the stream is terminated+--+-- The analogue of @List.last@+lastStream :: Iteratee [el] m el+lastStream = liftI (step Nothing)+  where+  step l (Chunk xs)+    | nullC xs     = liftI (step l)+    | otherwise    = liftI $ step (Just $ last xs)+  step l s@(EOF _) = case l of+    Nothing -> icont (step l) . Just . setEOF $ s+    Just x  -> idone x s+{-# INLINE lastStream #-}+++-- |Given a sequence of characters, attempt to match them against+-- the characters on the stream.  Return the count of how many+-- characters matched.  The matched characters are removed from the+-- stream.+-- For example, if the stream contains 'abd', then (heads 'abc')+-- will remove the characters 'ab' and return 2.+heads :: (Monad m, Eq el) => [el] -> Iteratee [el] m Int+heads st | nullC st = return 0+heads st = loopE 0 st+  where+  loopE cnt xs+    | nullC xs  = return cnt+    | otherwise = liftI (step cnt xs)+  step cnt str (Chunk [])          = liftI (step cnt str)+  step cnt [ ] stream              = idone cnt stream+  step cnt (y:ys) s@(Chunk (x:xs))+    | y == x    = step (succ cnt) ys (Chunk xs)+    | otherwise = idone cnt s+  step cnt _ stream         = idone cnt stream+{-# INLINE heads #-}+++-- |Look ahead at the next element of the stream, without removing+-- it from the stream.+-- Return @Just c@ if successful, return @Nothing@ if the stream is+-- terminated by 'EOF'.+peekStream :: Iteratee [el] m (Maybe el)+peekStream = liftI step+  where+    step   (Chunk [   ]) = liftI step+    step s@(Chunk (x:_)) = idone (Just x) s+    step stream          = idone Nothing stream+{-# INLINE peekStream #-}++-- | Return a chunk of @t@ elements length while consuming @d@ elements+--   from the stream.  Useful for creating a 'rolling average' with+--  'convStream'.+roll+  :: Monad m+  => Int  -- ^ length of chunk (t)+  -> Int  -- ^ amount to consume (d)+  -> Iteratee [el] m [[el]]+roll t d | t > d  = liftI step+  where+    step (Chunk vec)+      | length vec >= t =+          idone [take t vec] (Chunk $ drop d vec)+      | null vec        = liftI step+      | otherwise          = liftI (step' vec)+    step stream            = idone empty stream+    step' v1 (Chunk vec)   = step . Chunk $ v1 `mappend` vec+    step' v1 stream        = idone [v1] stream+roll t d = do r <- joinI (takeStream t stream2stream)+              dropStream (d-t)+              return [r]+  -- d is >= t, so this version works+{-# INLINE roll #-}+++-- |Drop n elements of the stream, if there are that many.+--+-- The analogue of @List.drop@+dropStream :: Int -> Iteratee [el] m ()+dropStream 0  = idone () (Chunk emptyP)+dropStream n' = liftI (step n')+  where+    step n (Chunk str)+      | length str < n = liftI (step (n - length str))+      | otherwise         = idone () (Chunk (drop n str))+    step _ stream         = idone () stream+{-# INLINE dropStream #-}++-- |Skip all elements while the predicate is true.+--+-- The analogue of @List.dropWhile@+dropWhileStream :: (el -> Bool) -> Iteratee [el] m ()+dropWhileStream p = liftI step+  where+    step (Chunk str)+      | null rest = liftI step+      | otherwise    = idone () (Chunk rest)+      where+        rest = dropWhile p str+    step stream      = idone () stream+{-# INLINE dropWhileStream #-}+++-- | Return the total length of the remaining part of the stream.+--+-- This forces evaluation of the entire stream.+--+-- The analogue of @List.length@+lengthStream :: Num a => Iteratee [el] m a+lengthStream = liftI (step 0)+  where+    step !i (Chunk xs) = liftI (step $ i + fromIntegral (length xs))+    step !i stream     = idone i stream+{-# INLINE lengthStream #-}++-- | Get the length of the current chunk, or @Nothing@ if 'EOF'.+--+-- This function consumes no input.+chunkLength :: Iteratee [el] m (Maybe Int)+chunkLength = liftI step+ where+  step s@(Chunk xs) = idone (Just $ length xs) s+  step stream       = idone Nothing stream+{-# INLINE chunkLength #-}++-- | Take @n@ elements from the current chunk, or the whole chunk if+-- @n@ is greater.+takeFromChunk :: Int -> Iteratee [el] m [el]+takeFromChunk n | n <= 0 = idone emptyP (Chunk emptyP)+takeFromChunk n = liftI step+ where+  step (Chunk xs) = let (h,t) = splitAt n xs in idone h $ Chunk t+  step stream     = idone emptyP stream+{-# INLINE takeFromChunk #-}++-- |Takes an element predicate and returns the (possibly empty) prefix of+-- the stream.  None of the characters in the string satisfy the character+-- predicate.+-- If the stream is not terminated, the first character of the remaining stream+-- satisfies the predicate.+--+-- N.B. 'breakE' should be used in preference to @breakStream@.+-- @breakStream@ will retain all data until the predicate is met, which may+-- result in a space leak.+--+-- The analogue of @List.break@++breakStream :: (el -> Bool) -> Iteratee [el] m [el]+breakStream cpred = icont (step mempty) Nothing+  where+    step bfr (Chunk str)+      | null str          =  icont (step bfr) Nothing+      | otherwise         =  case break cpred str of+        (str', tail')+          | null tail'    -> icont (step (bfr `mappend` str)) Nothing+          | otherwise     -> idone (bfr `mappend` str') (Chunk tail')+    step bfr stream       =  idone bfr stream+{-# INLINE breakStream #-}++-- ---------------------------------------------------+-- The converters show a different way of composing two iteratees:+-- `vertical' rather than `horizontal'++-- |Takes an element predicate and an iteratee, running the iteratee+-- on all elements of the stream until the predicate is met.+--+-- the following rule relates @break@ to @breakE@+-- @break@ pred === @joinI@ (@breakE@ pred stream2stream)+--+-- @breakE@ should be used in preference to @break@ whenever possible.+breakE :: (el -> Bool) -> Enumeratee [el] [el] m a+breakE cpred = eneeCheckIfDonePass (icont . step)+ where+  step k (Chunk s)+      | null s  = liftI (step k)+      | otherwise  = case break cpred s of+        (str', tail')+          | null tail'    -> eneeCheckIfDonePass (icont . step) . k $ Chunk str'+          | otherwise     -> idone (k $ Chunk str') (Chunk tail')+  step k stream           =  idone (liftI k) stream+{-# INLINE breakE #-}++-- |Read n elements from a stream and apply the given iteratee to the+-- stream of the read elements. Unless the stream is terminated early, we+-- read exactly n elements, even if the iteratee has accepted fewer.+--+-- The analogue of @List.take@+takeStream ::+  Monad m+  => Int   -- ^ number of elements to consume+  -> Enumeratee [el] [el] m a+takeStream n' iter+ | n' <= 0   = return iter+ | otherwise = Iteratee $ \od oc -> runIter iter (on_done od oc) (on_cont od oc)+  where+    on_done od oc x _ = runIter (dropStream n' >> return (return x)) od oc+    on_cont od oc k Nothing = if n' == 0 then od (liftI k) (Chunk mempty)+                                 else runIter (liftI (step n' k)) od oc+    on_cont od oc _ (Just e) = runIter (dropStream n' >> throwErr e) od oc+    step n k (Chunk str)+      | null str           = liftI (step n k)+      | length str <= n    = takeStream (n - length str) $ k (Chunk str)+      | otherwise          = idone (k (Chunk s1)) (Chunk s2)+      where (s1, s2) = splitAt n str+    step _n k stream       = idone (liftI k) stream+{-# INLINE takeStream #-}++-- |Read n elements from a stream and apply the given iteratee to the+-- stream of the read elements. If the given iteratee accepted fewer+-- elements, we stop.+-- This is the variation of 'takeStream' with the early termination+-- of processing of the outer stream once the processing of the inner stream+-- finished early.+--+-- Iteratees composed with 'takeUpTo' will consume only enough elements to+-- reach a done state.  Any remaining data will be available in the outer+-- stream.+--+-- > > let iter = do+-- > h <- joinI $ takeUpTo 5 I.head+-- > t <- stream2list+-- > return (h,t)+-- >+-- > > enumPureNChunk [1..10::Int] 3 iter >>= run >>= print+-- > (1,[2,3,4,5,6,7,8,9,10])+-- >+-- > > enumPureNChunk [1..10::Int] 7 iter >>= run >>= print+-- > (1,[2,3,4,5,6,7,8,9,10])+--+-- in each case, @I.head@ consumes only one element, returning the remaining+-- 4 elements to the outer stream+takeUpTo :: Monad m => Int -> Enumeratee [el] [el] m a+takeUpTo i iter+ | i <= 0    = idone iter (Chunk emptyP)+ | otherwise = Iteratee $ \od oc ->+    runIter iter (onDone od oc) (onCont od oc)+  where+    onDone od oc x str      = runIter (idone (return x) str) od oc+    onCont od oc k Nothing  = if i == 0 then od (liftI k) (Chunk mempty)+                                 else runIter (liftI (step i k)) od oc+    onCont od oc _ (Just e) = runIter (throwErr e) od oc+    step n k (Chunk str)+      | null str       = liftI (step n k)+      | length str < n = takeUpTo (n - length str) $ k (Chunk str)+      | otherwise      =+         -- check to see if the inner iteratee has completed, and if so,+         -- grab any remaining stream to put it in the outer iteratee.+         -- the outer iteratee is always complete at this stage, although+         -- the inner may not be.+         let (s1, s2) = splitAt n str+         in Iteratee $ \od' _ -> do+              res <- runIter (k (Chunk s1)) (\a s  -> return $ Left  (a, s))+                                            (\k' e -> return $ Right (k',e))+              case res of+                Left (a,Chunk s1') -> od' (return a)+                                          (Chunk $ s1' ++ s2)+                Left  (a,s')       -> od' (idone a s') (Chunk s2)+                Right (k',e)       -> od' (icont k' e) (Chunk s2)+    step _ k stream       = idone (liftI k) stream+{-# INLINE takeUpTo #-}+++-- |Takes an element predicate and an iteratee, running the iteratee+-- on all elements of the stream while the predicate is met.+--+-- This is preferred to @takeWhile@.+takeWhileE :: (el -> Bool) -> Enumeratee [el] [el] m a+takeWhileE = breakE . (not .)+{-# INLINEABLE takeWhileE #-}++-- | Map a function over an 'Iteratee'.+-- This one is reimplemented and differs from the the one in+-- "Data.Iteratee.ListLike" in so far that it doesn't pass on an 'EOF'+-- received in the input, which is the expected behavior.+mapStream :: (el -> el') -> Enumeratee [el] [el'] m a+mapStream = mapChunks . map+{-# INLINE mapStream #-}++-- | Apply a function to the elements of a stream, concatenate the+-- results into a stream.  No giant intermediate list is produced.+concatMapStream :: Monoid t => (a -> t) -> Enumeratee [a] t m r+concatMapStream = mapChunks . foldMap+{-# INLINE concatMapStream #-}++-- | Apply a monadic function to the elements of a stream, concatenate+-- the results into a stream.  No giant intermediate list is produced.+concatMapStreamM :: Monad m => (a -> m t) -> Enumeratee [a] t m r+concatMapStreamM f = eneeCheckIfDone (liftI . go)+  where+    go k (EOF   mx)              = idone (liftI k) (EOF mx)+    go k (Chunk xs) | null xs    = liftI (go k)+                    | otherwise  = f (head xs) `mBind`+                                   eneeCheckIfDone (flip go (Chunk (tail xs))) . k . Chunk+{-# INLINE concatMapStreamM #-}++mapMaybeStream :: (a -> Maybe b) -> Enumeratee [a] [b] m r+mapMaybeStream = mapChunks . mapMaybe+{-# INLINE mapMaybeStream #-}++-- |Creates an 'enumeratee' with only elements from the stream that+-- satisfy the predicate function.  The outer stream is completely consumed.+--+-- The analogue of @List.filter@+filterStream :: (el -> Bool) -> Enumeratee [el] [el] m a+filterStream p = mapChunks (filter p)+{-# INLINE filterStream #-}++-- | Apply a monadic filter predicate to an 'Iteratee'.+filterStreamM :: Monad m => (a -> m Bool) -> Enumeratee [a] [a] m r+filterStreamM k = mapChunksM (go id)+  where+    go acc [   ] = return $! acc empty+    go acc (h:t) = do p <- k h+                      let acc' = if p then (:) h . acc else acc+                      go acc' t+{-# INLINE filterStreamM #-}++-- | Grouping on 'Iteratee's.  @groupStreamOn proj inner outer@ executes+-- @inner (proj e)@, where @e@ is the first input element, to obtain an+-- 'Iteratee' @i@, then passes elements @e@ to @i@ as long as @proj e@+-- produces the same result.  If @proj e@ changes or the input ends, the+-- pair of @proj e@ and the result of @run i@ is passed to @outer@.  At+-- end of input, the resulting @outer@ is returned.+groupStreamOn :: (Monad m, Eq t1)+              => (e -> t1)+              -> (t1 -> m (Iteratee [e] m t2))+              -> Enumeratee [e] [(t1, t2)] m a+groupStreamOn proj inner = eneeCheckIfDonePass (icont . step)+  where+    step outer   (EOF      mx) = idone (liftI outer) $ EOF mx+    step outer   (Chunk [   ]) = liftI $ step outer+    step outer c@(Chunk (h:_)) = let x = proj h+                                 in lift (inner x) >>= \i -> step' x i outer c++    -- We want to feed a 'Chunk' to the inner 'Iteratee', which might be+    -- finished.  In that case, we would want to abort, but we cannot,+    -- since the outer iteration is still going on.  So instead we+    -- discard data we would have fed to the inner 'Iteratee'.  (Use of+    -- 'enumPure1Chunk' is not appropriate, it would accumulate the+    -- data, just to have it discarded by the 'run' that eventually+    -- happens.++    step' c it outer (Chunk as)+        | null as = liftI $ step' c it outer+        | (l,r) <- span ((==) c . proj) as, not (null l) =+            let od a    _str = idoneM a $ EOF Nothing+                oc k Nothing = return $ k (Chunk l)+                oc k       m = icontM k m+            in lift (runIter it od oc) >>= \it' -> step' c it' outer (Chunk r)++    step' c it outer str =+        lift (run it) >>= \b -> eneeCheckIfDone (`step` str) . outer $ Chunk [(c,b)]+++-- | Grouping on 'Iteratee's.  @groupStreamBy cmp inner outer@ executes+-- @inner@ to obtain an 'Iteratee' @i@, then passes elements @e@ to @i@+-- as long as @cmp e0 e@, where @e0@ is some preceeding element, is+-- true.  Else, the result of @run i@ is passed to @outer@ and+-- 'groupStreamBy' restarts.  At end of input, the resulting @outer@ is+-- returned.+groupStreamBy :: Monad m+              => (t -> t -> Bool)+              -> m (Iteratee [t] m t2)+              -> Enumeratee [t] [t2] m a+groupStreamBy cmp inner = eneeCheckIfDonePass (icont . step)+  where+    step outer   (EOF      mx) = idone (liftI outer) $ EOF mx+    step outer   (Chunk [   ]) = liftI $ step outer+    step outer c@(Chunk (h:_)) = lift inner >>= \i -> step' h i outer c++    step' c it outer (Chunk as)+        | null as = liftI $ step' c it outer+        | (l,r) <- span (cmp c) as, not (null l) =+            let od a    _str = idoneM a $ EOF Nothing+                oc k Nothing = return $ k (Chunk l)+                oc k       m = icontM k m+            in lift (runIter it od oc) >>= \it' -> step' (head l) it' outer (Chunk r)++    step' _ it outer str =+        lift (run it) >>= \b -> eneeCheckIfDone (`step` str) . outer $ Chunk [b]+++-- | @mergeStreams@ offers another way to nest iteratees: as a monad stack.+-- This allows for the possibility of interleaving data from multiple+-- streams.+--+-- > -- print each element from a stream of lines.+-- > logger :: (MonadIO m) => Iteratee [ByteString] m ()+-- > logger = mapStreamM_ (liftIO . putStrLn . B.unpack)+-- >+-- > -- combine alternating lines from two sources+-- > -- To see how this was derived, follow the types from+-- > -- 'ileaveLines logger' and work outwards.+-- > run =<< enumFile 10 "file1" (joinI $ enumLinesBS $+-- >           ( enumFile 10 "file2" . joinI . enumLinesBS $ joinI+-- >                 (ileaveLines logger)) >>= run)+-- >+-- > ileaveLines :: (Functor m, Monad m)+-- >   => Enumeratee [ByteString] [ByteString] (Iteratee [ByteString] m)+-- >        [ByteString]+-- > ileaveLines = mergeStreams (\l1 l2 ->+-- >    [B.pack "f1:\n\t" ,l1 ,B.pack "f2:\n\t" ,l2 ]+-- >+-- >+--+mergeStreams :: Monad m => (el1 -> el2 -> b) -> Enumeratee [el2] b (Iteratee [el1] m) a+mergeStreams f = convStream $ liftM2 f (lift headStream) headStream+{-# INLINE mergeStreams #-}++-- | A version of mergeStreams which operates on chunks instead of+-- elements.+--+-- mergeByChunks offers more control than 'mergeStreams'.+-- 'mergeStreams' terminates when the first stream terminates, however+-- mergeByChunks will continue until both streams are exhausted.+--+-- 'mergeByChunks' guarantees that both chunks passed to the merge+-- function will have the same number of elements, although that number+-- may vary between calls.+mergeByChunks ::+  Monad m+  => ([el1] -> [el2] -> c3)  -- ^ merge function+  -> ([el1] -> c3)+  -> ([el2] -> c3)+  -> Enumeratee [el2] c3 (Iteratee [el1] m) a+mergeByChunks f f1 f2 = unfoldConvStream iter (0 :: Int)+ where+  iter 1 = (\x -> (1,f1 x)) `liftM` lift getChunk+  iter 2 = (\x -> (2,f2 x)) `liftM` getChunk+  iter _ = do+    ml1 <- lift chunkLength+    ml2 <- chunkLength+    case (ml1, ml2) of+      (Just l1, Just l2) -> do+        let tval = min l1 l2+        c1 <- lift $ takeFromChunk tval+        c2 <- takeFromChunk tval+        return (0, f c1 c2)+      (Just _, Nothing) -> iter 1+      (Nothing, _)      -> iter 2+{-# INLINE mergeByChunks #-}++-- ------------------------------------------------------------------------+-- Folds++-- | Left-associative fold that is strict in the accumulator.+-- This function should be used in preference to 'foldl' whenever possible.+--+-- The analogue of @List.foldl'@.+foldStream :: (a -> el -> a) -> a -> Iteratee [el] m a+foldStream f i = liftI (step i)+  where+    step acc (Chunk xs)+      | null xs = liftI (step acc)+      | otherwise  = liftI (step $! foldl' f acc xs)+    step acc stream = idone acc stream+{-# INLINE foldStream #-}++-- ------------------------------------------------------------------------+-- Zips++-- |Enumerate two iteratees over a single stream simultaneously.+--+-- Compare to @List.zip@.+zipStreams+  :: Monad m+  => Iteratee [el] m a+  -> Iteratee [el] m b+  -> Iteratee [el] m (a, b)+zipStreams x0 y0 = do+    -- need to check if both iteratees are initially finished.  If so,+    -- we don't want to push a chunk which will be dropped+    (a', x') <- lift $ runIter x0 od oc+    (b', y') <- lift $ runIter y0 od oc+    case checkDone a' b' of+      Just (Right (a,b,s))  -> idone (a,b) s  -- 's' may be EOF, needs to stay+      Just (Left (Left a))  -> liftM (a,) y'+      Just (Left (Right b)) -> liftM (,b) x'+      Nothing               -> liftI (step x' y')+  where+    step x y (Chunk xs) | nullC xs = liftI (step x y)+    step x y (Chunk xs) = do+      (a', x') <- lift $ (\i -> runIter i od oc) =<< enumPure1Chunk xs x+      (b', y') <- lift $ (\i -> runIter i od oc) =<< enumPure1Chunk xs y+      case checkDone a' b' of+        Just (Right (a,b,s))  -> idone (a,b) s+        Just (Left (Left a))  -> liftM (a,) y'+        Just (Left (Right b)) -> liftM (,b) x'+        Nothing               -> liftI (step x' y')+    step x y (EOF err) = joinIM $ case err of+      Nothing -> (liftM2.liftM2) (,) (enumEof   x) (enumEof   y)+      Just e  -> (liftM2.liftM2) (,) (enumErr e x) (enumErr e y)++    od a s = return (Just (a, s), idone a s)+    oc k e = return (Nothing    , icont k e)++    checkDone r1 r2 = case (r1, r2) of+      (Just (a, s1), Just (b,s2)) -> Just $ Right (a, b, shorter s1 s2)+      (Just (a, _), Nothing)      -> Just . Left $ Left a+      (Nothing, Just (b, _))      -> Just . Left $ Right b+      (Nothing, Nothing)          -> Nothing++    shorter c1@(Chunk xs) c2@(Chunk ys)+      | length xs < length ys = c1+      | otherwise                   = c2+    shorter e@(EOF _)  _         = e+    shorter _          e@(EOF _) = e+{-# INLINE zipStreams #-}++zipStreams3+  :: Monad m+  => Iteratee [el] m a -> Iteratee [el] m b+  -> Iteratee [el] m c -> Iteratee [el] m (a, b, c)+zipStreams3 a b c = zipStreams a (zipStreams b c) >>=+  \(r1, (r2, r3)) -> return (r1, r2, r3)+{-# INLINE zipStreams3 #-}++zipStreams4+  :: Monad m+  => Iteratee [el] m a -> Iteratee [el] m b+  -> Iteratee [el] m c -> Iteratee [el] m d+  -> Iteratee [el] m (a, b, c, d)+zipStreams4 a b c d = zipStreams a (zipStreams3 b c d) >>=+  \(r1, (r2, r3, r4)) -> return (r1, r2, r3, r4)+{-# INLINE zipStreams4 #-}++zipStreams5+  :: Monad m+  => Iteratee [el] m a -> Iteratee [el] m b+  -> Iteratee [el] m c -> Iteratee [el] m d+  -> Iteratee [el] m e -> Iteratee [el] m (a, b, c, d, e)+zipStreams5 a b c d e = zipStreams a (zipStreams4 b c d e) >>=+  \(r1, (r2, r3, r4, r5)) -> return (r1, r2, r3, r4, r5)+{-# INLINE zipStreams5 #-}++-- | Enumerate over two iteratees in parallel as long as the first iteratee+-- is still consuming input.  The second iteratee will be terminated with EOF+-- when the first iteratee has completed.  An example use is to determine+-- how many elements an iteratee has consumed:+--+-- > snd <$> enumWith (dropWhile (<5)) length+--+-- Compare to @zipStreams@+enumWith+  :: Monad m+  => Iteratee [el] m a+  -> Iteratee [el] m b+  -> Iteratee [el] m (a, b)+enumWith i1 i2 = do+    -- as with zipStreams, first check to see if the initial iteratee is complete,+    -- otherwise data would be dropped.+    -- running the second iteratee as well to prevent a monadic effect mismatch+    -- although I think that would be highly unlikely to happen in common+    -- code+    (a', x') <- lift $ runIter i1 od oc+    (_,  y') <- lift $ runIter i2 od oc+    case a' of+      Just (a, s) -> flip idone s =<< lift (liftM (a,) $ run i2)+      Nothing     -> go x' y'+  where+    od a s = return (Just (a, s), idone a s)+    oc k e = return (Nothing    , icont k e)++    getUsed xs (Chunk ys) = take (length xs - length ys) xs+    getUsed xs (EOF _)    = xs++    go x y = liftI step+      where+        step (Chunk xs) | nullC xs = liftI step+        step (Chunk xs) = do+          (a', x') <- lift $ (\i -> runIter i od oc) =<< enumPure1Chunk xs x+          case a' of+            Just (a, s) -> do+              b <- lift $ run =<< enumPure1Chunk (getUsed xs s) y+              idone (a, b) s+            Nothing        -> lift (enumPure1Chunk xs y) >>= go x'+        step (EOF err) = joinIM $ case err of+          Nothing -> (liftM2.liftM2) (,) (enumEof   x) (enumEof   y)+          Just e  -> (liftM2.liftM2) (,) (enumErr e x) (enumErr e y)+{-# INLINE enumWith #-}++-- |Enumerate a list of iteratees over a single stream simultaneously+-- and discard the results. This is a different behavior than Prelude's+-- sequence_ which runs iteratees in the list one after the other.+--+-- Compare to @Prelude.sequence_@.+sequenceStreams_+  :: Monad m+  => [Iteratee [el] m a]+  -> Iteratee [el] m ()+sequenceStreams_ = self+  where+    self is = liftI step+      where+        step (Chunk xs) | null xs = liftI step+        step s@(Chunk _) = do+          -- give a chunk to each iteratee+          is'  <- lift $ mapM (enumChunk s) is+          -- filter done iteratees+          (done, notDone) <- lift $ partition fst `liftM` mapM enumCheckIfDone is'+          if null notDone+            then idone () <=< remainingStream $ map snd done+            else self $ map snd notDone+        step s@(EOF _) = do+          s' <- remainingStream <=< lift $ mapM (enumChunk s) is+          case s' of+            EOF (Just e) -> throwErr e+            _            -> idone () s'++    -- returns the unconsumed part of the stream; "sequenceStreams_ is" consumes as+    -- much of the stream as the iteratee in is that consumes the most; e.g.+    -- sequenceStreams_ [I.head, I.last] consumes whole stream+    remainingStream :: Monad m => [Iteratee [el] m a] -> Iteratee [el] m (Stream [el])+    remainingStream is = lift $+      return . foldl1 shorter <=< mapM (\i -> runIter i od oc) $ is+      where+        od _ s = return s+        oc _ e = return $ case e of+          Nothing -> mempty+          _       -> EOF e++    -- return the shorter one of two streams; errors are propagated with the+    -- priority given to the "left"+    shorter c1@(Chunk xs) c2@(Chunk ys)+      | length xs < length ys = c1+      | otherwise                   = c2+    shorter (EOF e1 ) (EOF e2 ) = EOF (e1 `mplus` e2)+    shorter e@(EOF _) _         = e+    shorter _         e@(EOF _) = e++-- |Transform an iteratee into one that keeps track of how much data it+-- consumes.+countConsumed :: (Monad m, Integral n) => Iteratee [el] m a -> Iteratee [el] m (a, n)+countConsumed i = go 0 (const i) (Chunk emptyP)+  where+    go !n f str@(EOF _) = (, n) `liftM` f str+    go !n f str@(Chunk c) = Iteratee rI+      where+        newLen = n + fromIntegral (length c)+        rI od oc = runIter (f str) onDone onCont+          where+            onDone a str'@(Chunk c') =+                od (a, newLen - fromIntegral (length c')) str'+            onDone a str'@(EOF _) = od (a, n) str'+            onCont f' mExc = oc (go newLen f') mExc+{-# INLINE countConsumed #-}++-- ------------------------------------------------------------------------+-- Enumerators++-- |The pure n-chunk enumerator+-- It passes a given stream of elements to the iteratee in @n@-sized chunks.+enumPureNChunk :: Monad m => [el] -> Int -> Enumerator [el] m a+enumPureNChunk str n iter+  | null str = return iter+  | n > 0       = enum' str iter+  | otherwise   = error $ "enumPureNChunk called with n==" ++ show n+  where+    enum' str' iter'+      | null str' = return iter'+      | otherwise    = let (s1, s2) = splitAt n str'+                           on_cont k Nothing = enum' s2 . k $ Chunk s1+                           on_cont k e = return $ icont k e+                       in runIter iter' idoneM on_cont+{-# INLINE enumPureNChunk #-}++-- ------------------------------------------------------------------------+-- Monadic functions++-- | Maps a monadic function over the elements of the stream and ignores+-- the result.+mapStreamM_ :: Monad m => (el -> m b) -> Iteratee [el] m ()+mapStreamM_ = mapChunksM_ . mapM_+{-# INLINE mapStreamM_ #-}++-- | Maps a monadic function over an 'Iteratee'.+mapStreamM :: Monad m => (el -> m el') -> Enumeratee [el] [el'] m a+mapStreamM = mapChunksM . mapM+{-# INLINE mapStreamM #-}++-- | Folds a monadic function over an 'Iteratee'.+foldStreamM :: Monad m => (b -> a -> m b) -> b -> Iteratee [a] m b+foldStreamM k = foldChunksM go+  where+    go b [   ] = return b+    go b (h:t) = k b h >>= \b' -> go b' t+{-# INLINE foldStreamM #-}
− src/Bio/Iteratee/ListLike.hs
@@ -1,883 +0,0 @@-{-# LANGUAGE TupleSections, ScopedTypeVariables #-}---- |Monadic Iteratees:--- incremental input parsers, processors and transformers------ This module provides many basic iteratees from which more complicated--- iteratees can be built.  In general these iteratees parallel those in--- @Data.List@, with some additions.--module Bio.Iteratee.ListLike (-  -- * Iteratees-  -- ** Iteratee Utilities-  isFinished-  ,stream2list-  ,stream2stream-  -- ** Basic Iteratees-  ,dropWhileStream-  ,dropStream-  ,headStream-  ,tryHead-  ,lastStream-  ,heads-  ,peekStream-  ,roll-  ,lengthStream-  ,chunkLength-  ,takeFromChunk-  -- ** Nested iteratee combinators-  ,breakStream-  ,breakE-  ,takeStream-  ,takeUpTo-  ,takeWhileE-  ,mapStream-  ,concatMapStream-  ,concatMapStreamM-  ,mapMaybeStream-  ,rigidMapStream-  ,filterStream-  ,filterStreamM-  ,groupStreamBy-  ,groupStreamOn-  ,mergeStreams-  ,mergeByChunks-  -- ** Folds-  ,foldStream-  -- * Enumerators-  -- ** Basic enumerators-  ,enumPureNChunk-  -- ** Enumerator Combinators-  ,enumWith-  ,zipStreams-  ,zipStreams3-  ,zipStreams4-  ,zipStreams5-  ,sequenceStreams_-  ,countConsumed-  -- ** Monadic functions-  ,mapStreamM-  ,mapStreamM_-  ,foldStreamM-  -- * Re-exported modules-  ,module Bio.Iteratee.Iteratee-)-where--import Bio.Iteratee.Iteratee-import Bio.Prelude-import Control.Monad.Trans.Class--import qualified Data.ByteString          as B-import qualified Data.ListLike            as LL-import qualified Data.ListLike.FoldableLL as FLL----- Useful combinators for implementing iteratees and enumerators---- | Check if a stream has received 'EOF'.-isFinished :: (Nullable s) => Iteratee s m Bool-isFinished = liftI check-  where-  check c@(Chunk xs)-    | nullC xs    = liftI check-    | otherwise   = idone False c-  check s@(EOF _) = idone True s-{-# INLINE isFinished #-}---- --------------------------------------------------------------------------- Primitive iteratees---- |Read a stream to the end and return all of its elements as a list.--- This iteratee returns all data from the stream *strictly*.-stream2list :: (Monad m, Nullable s, LL.ListLike s el) => Iteratee s m [el]-stream2list = liftM (concatMap LL.toList) getChunks-{-# INLINE stream2list #-}---- |Read a stream to the end and return all of its elements as a stream.--- This iteratee returns all data from the stream *strictly*.-stream2stream :: (Monad m, Nullable s, Monoid s) => Iteratee s m s-stream2stream = liftM mconcat getChunks-{-# INLINE stream2stream #-}----- --------------------------------------------------------------------------- Parser combinators---- |Attempt to read the next element of the stream and return it--- Raise a (recoverable) error if the stream is terminated.------ The analogue of @List.head@------ Because @head@ can raise an error, it shouldn't be used when constructing--- iteratees for @convStream@.  Use @tryHead@ instead.-headStream :: (LL.ListLike s el) => Iteratee s m el-headStream = liftI step-  where-  step (Chunk vec)-    | LL.null vec  = icont step Nothing-    | otherwise    = idone (LL.head vec) (Chunk $ LL.tail vec)-  step stream      = icont step (Just (setEOF stream))-{-# INLINE headStream #-}---- | Similar to @headStream@, except it returns @Nothing@ if the stream--- is terminated.-tryHead :: (LL.ListLike s el) => Iteratee s m (Maybe el)-tryHead = liftI step-  where-  step (Chunk vec)-    | LL.null vec  = liftI step-    | otherwise    = idone (Just $ LL.head vec) (Chunk $ LL.tail vec)-  step stream      = idone Nothing stream-{-# INLINE tryHead #-}---- |Attempt to read the last element of the stream and return it--- Raise a (recoverable) error if the stream is terminated------ The analogue of @List.last@-lastStream :: (LL.ListLike s el, Nullable s) => Iteratee s m el-lastStream = liftI (step Nothing)-  where-  step l (Chunk xs)-    | nullC xs     = liftI (step l)-    | otherwise    = liftI $ step (Just $ LL.last xs)-  step l s@(EOF _) = case l of-    Nothing -> icont (step l) . Just . setEOF $ s-    Just x  -> idone x s-{-# INLINE lastStream #-}----- |Given a sequence of characters, attempt to match them against--- the characters on the stream.  Return the count of how many--- characters matched.  The matched characters are removed from the--- stream.--- For example, if the stream contains 'abd', then (heads 'abc')--- will remove the characters 'ab' and return 2.-heads :: (Monad m, Nullable s, LL.ListLike s el, Eq el) => s -> Iteratee s m Int-heads st | nullC st = return 0-heads st = loopE 0 st-  where-  loopE cnt xs-    | nullC xs  = return cnt-    | otherwise = liftI (step cnt xs)-  step cnt str (Chunk xs) | nullC xs  = liftI (step cnt str)-  step cnt str stream     | nullC str = idone cnt stream-  step cnt str s@(Chunk xs) =-    if LL.head str == LL.head xs-       then step (succ cnt) (LL.tail str) (Chunk $ LL.tail xs)-       else idone cnt s-  step cnt _ stream         = idone cnt stream-{-# INLINE heads #-}----- |Look ahead at the next element of the stream, without removing--- it from the stream.--- Return @Just c@ if successful, return @Nothing@ if the stream is--- terminated by 'EOF'.-peekStream :: (LL.ListLike s el) => Iteratee s m (Maybe el)-peekStream = liftI step-  where-    step s@(Chunk vec)-      | LL.null vec = liftI step-      | otherwise   = idone (Just $ LL.head vec) s-    step stream     = idone Nothing stream-{-# INLINE peekStream #-}---- | Return a chunk of @t@ elements length while consuming @d@ elements---   from the stream.  Useful for creating a 'rolling average' with---  'convStream'.-roll-  :: (Monad m, Nullable s, LL.ListLike s el, LL.ListLike s' s)-  => Int  -- ^ length of chunk (t)-  -> Int  -- ^ amount to consume (d)-  -> Iteratee s m s'-roll t d | t > d  = liftI step-  where-    step (Chunk vec)-      | LL.length vec >= t =-          idone (LL.singleton $ LL.take t vec) (Chunk $ LL.drop d vec)-      | LL.null vec        = liftI step-      | otherwise          = liftI (step' vec)-    step stream            = idone LL.empty stream-    step' v1 (Chunk vec)   = step . Chunk $ v1 `mappend` vec-    step' v1 stream        = idone (LL.singleton v1) stream-roll t d = do r <- joinI (takeStream t stream2stream)-              dropStream (d-t)-              return $ LL.singleton r-  -- d is >= t, so this version works-{-# INLINE roll #-}----- |Drop n elements of the stream, if there are that many.------ The analogue of @List.drop@-dropStream :: (Nullable s, LL.ListLike s el) => Int -> Iteratee s m ()-dropStream 0  = idone () (Chunk emptyP)-dropStream n' = liftI (step n')-  where-    step n (Chunk str)-      | LL.length str < n = liftI (step (n - LL.length str))-      | otherwise         = idone () (Chunk (LL.drop n str))-    step _ stream         = idone () stream-{-# INLINE dropStream #-}---- |Skip all elements while the predicate is true.------ The analogue of @List.dropWhile@-dropWhileStream :: (LL.ListLike s el) => (el -> Bool) -> Iteratee s m ()-dropWhileStream p = liftI step-  where-    step (Chunk str)-      | LL.null rest = liftI step-      | otherwise    = idone () (Chunk rest)-      where-        rest = LL.dropWhile p str-    step stream      = idone () stream-{-# INLINE dropWhileStream #-}----- | Return the total length of the remaining part of the stream.------ This forces evaluation of the entire stream.------ The analogue of @List.length@-lengthStream :: (Num a, LL.ListLike s el) => Iteratee s m a-lengthStream = liftI (step 0)-  where-    step !i (Chunk xs) = liftI (step $ i + fromIntegral (LL.length xs))-    step !i stream     = idone i stream-{-# INLINE lengthStream #-}---- | Get the length of the current chunk, or @Nothing@ if 'EOF'.------ This function consumes no input.-chunkLength :: (LL.ListLike s el) => Iteratee s m (Maybe Int)-chunkLength = liftI step- where-  step s@(Chunk xs) = idone (Just $ LL.length xs) s-  step stream       = idone Nothing stream-{-# INLINE chunkLength #-}---- | Take @n@ elements from the current chunk, or the whole chunk if--- @n@ is greater.-takeFromChunk ::-  (Nullable s, LL.ListLike s el)-  => Int-  -> Iteratee s m s-takeFromChunk n | n <= 0 = idone emptyP (Chunk emptyP)-takeFromChunk n = liftI step- where-  step (Chunk xs) = let (h,t) = LL.splitAt n xs in idone h $ Chunk t-  step stream     = idone emptyP stream-{-# INLINE takeFromChunk #-}---- |Takes an element predicate and returns the (possibly empty) prefix of--- the stream.  None of the characters in the string satisfy the character--- predicate.--- If the stream is not terminated, the first character of the remaining stream--- satisfies the predicate.------ N.B. 'breakE' should be used in preference to @breakStream@.--- @breakStream@ will retain all data until the predicate is met, which may--- result in a space leak.------ The analogue of @List.break@--breakStream :: (LL.ListLike s el) => (el -> Bool) -> Iteratee s m s-breakStream cpred = icont (step mempty) Nothing-  where-    step bfr (Chunk str)-      | LL.null str       =  icont (step bfr) Nothing-      | otherwise         =  case LL.break cpred str of-        (str', tail')-          | LL.null tail' -> icont (step (bfr `mappend` str)) Nothing-          | otherwise     -> idone (bfr `mappend` str') (Chunk tail')-    step bfr stream       =  idone bfr stream-{-# INLINE breakStream #-}---- ------------------------------------------------------ The converters show a different way of composing two iteratees:--- `vertical' rather than `horizontal'---- |Takes an element predicate and an iteratee, running the iteratee--- on all elements of the stream until the predicate is met.------ the following rule relates @break@ to @breakE@--- @break@ pred === @joinI@ (@breakE@ pred stream2stream)------ @breakE@ should be used in preference to @break@ whenever possible.-breakE-  :: (LL.ListLike s el, NullPoint s)-  => (el -> Bool)-  -> Enumeratee s s m a-breakE cpred = eneeCheckIfDonePass (icont . step)- where-  step k (Chunk s)-      | LL.null s  = liftI (step k)-      | otherwise  = case LL.break cpred s of-        (str', tail')-          | LL.null tail' -> eneeCheckIfDonePass (icont . step) . k $ Chunk str'-          | otherwise     -> idone (k $ Chunk str') (Chunk tail')-  step k stream           =  idone (liftI k) stream-{-# INLINE breakE #-}---- |Read n elements from a stream and apply the given iteratee to the--- stream of the read elements. Unless the stream is terminated early, we--- read exactly n elements, even if the iteratee has accepted fewer.------ The analogue of @List.take@-takeStream ::-  (Monad m, Nullable s, LL.ListLike s el)-  => Int   -- ^ number of elements to consume-  -> Enumeratee s s m a-takeStream n' iter- | n' <= 0   = return iter- | otherwise = Iteratee $ \od oc -> runIter iter (on_done od oc) (on_cont od oc)-  where-    on_done od oc x _ = runIter (dropStream n' >> return (return x)) od oc-    on_cont od oc k Nothing = if n' == 0 then od (liftI k) (Chunk mempty)-                                 else runIter (liftI (step n' k)) od oc-    on_cont od oc _ (Just e) = runIter (dropStream n' >> throwErr e) od oc-    step n k (Chunk str)-      | LL.null str        = liftI (step n k)-      | LL.length str <= n = takeStream (n - LL.length str) $ k (Chunk str)-      | otherwise          = idone (k (Chunk s1)) (Chunk s2)-      where (s1, s2) = LL.splitAt n str-    step _n k stream       = idone (liftI k) stream-{-# INLINE takeStream #-}---- |Read n elements from a stream and apply the given iteratee to the--- stream of the read elements. If the given iteratee accepted fewer--- elements, we stop.--- This is the variation of 'takeStream' with the early termination--- of processing of the outer stream once the processing of the inner stream--- finished early.------ Iteratees composed with 'takeUpTo' will consume only enough elements to--- reach a done state.  Any remaining data will be available in the outer--- stream.------ > > let iter = do--- > h <- joinI $ takeUpTo 5 I.head--- > t <- stream2list--- > return (h,t)--- >--- > > enumPureNChunk [1..10::Int] 3 iter >>= run >>= print--- > (1,[2,3,4,5,6,7,8,9,10])--- >--- > > enumPureNChunk [1..10::Int] 7 iter >>= run >>= print--- > (1,[2,3,4,5,6,7,8,9,10])------ in each case, @I.head@ consumes only one element, returning the remaining--- 4 elements to the outer stream-takeUpTo :: (Monad m, Nullable s, LL.ListLike s el) => Int -> Enumeratee s s m a-takeUpTo i iter- | i <= 0    = idone iter (Chunk emptyP)- | otherwise = Iteratee $ \od oc ->-    runIter iter (onDone od oc) (onCont od oc)-  where-    onDone od oc x str      = runIter (idone (return x) str) od oc-    onCont od oc k Nothing  = if i == 0 then od (liftI k) (Chunk mempty)-                                 else runIter (liftI (step i k)) od oc-    onCont od oc _ (Just e) = runIter (throwErr e) od oc-    step n k (Chunk str)-      | LL.null str       = liftI (step n k)-      | LL.length str < n = takeUpTo (n - LL.length str) $ k (Chunk str)-      | otherwise         =-         -- check to see if the inner iteratee has completed, and if so,-         -- grab any remaining stream to put it in the outer iteratee.-         -- the outer iteratee is always complete at this stage, although-         -- the inner may not be.-         let (s1, s2) = LL.splitAt n str-         in Iteratee $ \od' _ -> do-              res <- runIter (k (Chunk s1)) (\a s  -> return $ Left  (a, s))-                                            (\k' e -> return $ Right (k',e))-              case res of-                Left (a,Chunk s1') -> od' (return a)-                                          (Chunk $ s1' `LL.append` s2)-                Left  (a,s')       -> od' (idone a s') (Chunk s2)-                Right (k',e)       -> od' (icont k' e) (Chunk s2)-    step _ k stream       = idone (liftI k) stream-{-# INLINE takeUpTo #-}----- |Takes an element predicate and an iteratee, running the iteratee--- on all elements of the stream while the predicate is met.------ This is preferred to @takeWhile@.-takeWhileE- :: (LL.ListLike s el, NullPoint s)- => (el -> Bool)- -> Enumeratee s s m a-takeWhileE = breakE . (not .)-{-# INLINEABLE takeWhileE #-}---- | Map a function over an 'Iteratee'.--- This one is reimplemented and differs from the the one in--- "Data.Iteratee.ListLike" in so far that it doesn't pass on an 'EOF'--- received in the input, which is the expected behavior.-{-# INLINE mapStream #-}-mapStream :: (LL.ListLike (s el) el, LL.ListLike (s el') el', NullPoint (s el))-          => (el -> el') -> Enumeratee (s el) (s el') m a-mapStream = mapChunks . LL.map---- |Map the stream rigidly.------ Like 'mapStream', but the element type cannot change.--- This function is necessary for @ByteString@ and similar types--- that cannot have 'LooseMap' instances, and may be more efficient.-rigidMapStream-  :: (LL.ListLike s el, NullPoint s)-  => (el -> el)-  -> Enumeratee s s m a-rigidMapStream f = mapChunks (LL.rigidMap f)-{-# SPECIALIZE rigidMapStream :: (el -> el) -> Enumeratee [el] [el] m a #-}-{-# SPECIALIZE rigidMapStream :: (Word8 -> Word8) -> Enumeratee B.ByteString B.ByteString m a #-}----- | Apply a function to the elements of a stream, concatenate the--- results into a stream.  No giant intermediate list is produced.-{-# INLINE concatMapStream #-}-concatMapStream :: (Monad m, LL.ListLike s a, NullPoint s) => (a -> t) -> Enumeratee s t m r-concatMapStream f = eneeCheckIfDone (liftI . go)-  where-    go k (EOF   mx)              = idone (liftI k) (EOF mx)-    go k (Chunk xs) | LL.null xs = liftI (go k)-                    | otherwise  = eneeCheckIfDone (flip go (Chunk (LL.tail xs))) . k . Chunk . f $ LL.head xs---- | Apply a monadic function to the elements of a stream, concatenate--- the results into a stream.  No giant intermediate list is produced.-{-# INLINE concatMapStreamM #-}-concatMapStreamM :: (Monad m, LL.ListLike s a, NullPoint s) => (a -> m t) -> Enumeratee s t m r-concatMapStreamM f = eneeCheckIfDone (liftI . go)-  where-    go k (EOF   mx)              = idone (liftI k) (EOF mx)-    go k (Chunk xs) | LL.null xs = liftI (go k)-                    | otherwise  = f (LL.head xs) `mBind`-                                   eneeCheckIfDone (flip go (Chunk (LL.tail xs))) . k . Chunk--{-# INLINE mapMaybeStream #-}-mapMaybeStream :: (LL.ListLike s a, NullPoint s, LL.ListLike t b) => (a -> Maybe b) -> Enumeratee s t m r-mapMaybeStream f = mapChunks mm-  where-    mm l = if LL.null l then LL.empty else-           case f (LL.head l) of Nothing -> mm (LL.tail l)-                                 Just b  -> LL.cons b $ mm (LL.tail l)----- |Creates an 'enumeratee' with only elements from the stream that--- satisfy the predicate function.  The outer stream is completely consumed.------ The analogue of @List.filter@--- XXX filterStream :: (ListLike s a, NullPoint s) => (a -> Bool) -> Enumeratee s s m r-filterStream-  :: (NullPoint s, LL.ListLike s el)-  => (el -> Bool)-  -> Enumeratee s s m a-filterStream p = mapChunks (LL.filter p)-{-# INLINE filterStream #-}---- | Apply a monadic filter predicate to an 'Iteratee'.-{-# INLINE filterStreamM #-}-filterStreamM :: (Monad m, LL.ListLike s a, Nullable s) => (a -> m Bool) -> Enumeratee s s m r-filterStreamM k = mapChunksM (go id)-  where-    go acc s | LL.null s = return $! acc LL.empty-             | otherwise = do p <- k (LL.head s)-                              let acc' = if p then LL.cons (LL.head s) . acc else acc-                              go acc' (LL.tail s)---- | Grouping on 'Iteratee's.  @groupStreamOn proj inner outer@ executes--- @inner (proj e)@, where @e@ is the first input element, to obtain an--- 'Iteratee' @i@, then passes elements @e@ to @i@ as long as @proj e@--- produces the same result.  If @proj e@ changes or the input ends, the--- pair of @proj e@ and the result of @run i@ is passed to @outer@.  At--- end of input, the resulting @outer@ is returned.-groupStreamOn :: (Monad m, LL.ListLike l e, Eq t1, Nullable l)-              => (e -> t1)-              -> (t1 -> m (Iteratee l m t2))-              -> Enumeratee l [(t1, t2)] m a-groupStreamOn proj inner = eneeCheckIfDonePass (icont . step)-  where-    step outer   (EOF   mx) = idone (liftI outer) $ EOF mx-    step outer c@(Chunk as)-        | LL.null as = liftI $ step outer-        | otherwise  = let x = proj (LL.head as)-                       in lift (inner x) >>= \i -> step' x i outer c--    -- We want to feed a 'Chunk' to the inner 'Iteratee', which might be-    -- finished.  In that case, we would want to abort, but we cannot,-    -- since the outer iteration is still going on.  So instead we-    -- discard data we would have fed to the inner 'Iteratee'.  (Use of-    -- 'enumPure1Chunk' is not appropriate, it would accumulate the-    -- data, just to have it discarded by the 'run' that eventually-    -- happens.--    step' c it outer (Chunk as)-        | LL.null as = liftI $ step' c it outer-        | (l,r) <- LL.span ((==) c . proj) as, not (LL.null l) =-            let od a    _str = idoneM a $ EOF Nothing-                oc k Nothing = return $ k (Chunk l)-                oc k       m = icontM k m-            in lift (runIter it od oc) >>= \it' -> step' c it' outer (Chunk r)--    step' c it outer str =-        lift (run it) >>= \b -> eneeCheckIfDone (`step` str) . outer $ Chunk [(c,b)]----- | Grouping on 'Iteratee's.  @groupStreamBy cmp inner outer@ executes--- @inner@ to obtain an 'Iteratee' @i@, then passes elements @e@ to @i@--- as long as @cmp e0 e@, where @e0@ is some preceeding element, is--- true.  Else, the result of @run i@ is passed to @outer@ and--- 'groupStreamBy' restarts.  At end of input, the resulting @outer@ is--- returned.-groupStreamBy :: (Monad m, LL.ListLike l t, Nullable l)-              => (t -> t -> Bool)-              -> m (Iteratee l m t2)-              -> Enumeratee l [t2] m a-groupStreamBy cmp inner = eneeCheckIfDonePass (icont . step)-  where-    step outer    (EOF   mx) = idone (liftI outer) $ EOF mx-    step outer  c@(Chunk as)-        | LL.null as = liftI $ step outer-        | otherwise  = lift inner >>= \i -> step' (LL.head as) i outer c--    step' c it outer (Chunk as)-        | LL.null as = liftI $ step' c it outer-        | (l,r) <- LL.span (cmp c) as, not (LL.null l) =-            let od a    _str = idoneM a $ EOF Nothing-                oc k Nothing = return $ k (Chunk l)-                oc k       m = icontM k m-            in lift (runIter it od oc) >>= \it' -> step' (LL.head l) it' outer (Chunk r)--    step' _ it outer str =-        lift (run it) >>= \b -> eneeCheckIfDone (`step` str) . outer $ Chunk [b]----- | @mergeStreams@ offers another way to nest iteratees: as a monad stack.--- This allows for the possibility of interleaving data from multiple--- streams.------ > -- print each element from a stream of lines.--- > logger :: (MonadIO m) => Iteratee [ByteString] m ()--- > logger = mapStreamM_ (liftIO . putStrLn . B.unpack)--- >--- > -- combine alternating lines from two sources--- > -- To see how this was derived, follow the types from--- > -- 'ileaveLines logger' and work outwards.--- > run =<< enumFile 10 "file1" (joinI $ enumLinesBS $--- >           ( enumFile 10 "file2" . joinI . enumLinesBS $ joinI--- >                 (ileaveLines logger)) >>= run)--- >--- > ileaveLines :: (Functor m, Monad m)--- >   => Enumeratee [ByteString] [ByteString] (Iteratee [ByteString] m)--- >        [ByteString]--- > ileaveLines = mergeStreams (\l1 l2 ->--- >    [B.pack "f1:\n\t" ,l1 ,B.pack "f2:\n\t" ,l2 ]--- >--- >----mergeStreams ::-  (LL.ListLike s1 el1-   ,LL.ListLike s2 el2-   ,Nullable s1-   ,Nullable s2-   ,Monad m)-  => (el1 -> el2 -> b)-  -> Enumeratee s2 b (Iteratee s1 m) a-mergeStreams f = convStream $ liftM2 f (lift headStream) headStream-{-# INLINE mergeStreams #-}---- | A version of mergeStreams which operates on chunks instead of--- elements.------ mergeByChunks offers more control than 'mergeStreams'.--- 'mergeStreams' terminates when the first stream terminates, however--- mergeByChunks will continue until both streams are exhausted.------ 'mergeByChunks' guarantees that both chunks passed to the merge--- function will have the same number of elements, although that number--- may vary between calls.-mergeByChunks ::-  (Nullable c2, Nullable c1-  ,LL.ListLike c1 el1, LL.ListLike c2 el2-  , Monad m)-  => (c1 -> c2 -> c3)  -- ^ merge function-  -> (c1 -> c3)-  -> (c2 -> c3)-  -> Enumeratee c2 c3 (Iteratee c1 m) a-mergeByChunks f f1 f2 = unfoldConvStream iter (0 :: Int)- where-  iter 1 = (\x -> (1,f1 x)) `liftM` lift getChunk-  iter 2 = (\x -> (2,f2 x)) `liftM` getChunk-  iter _ = do-    ml1 <- lift chunkLength-    ml2 <- chunkLength-    case (ml1, ml2) of-      (Just l1, Just l2) -> do-        let tval = min l1 l2-        c1 <- lift $ takeFromChunk tval-        c2 <- takeFromChunk tval-        return (0, f c1 c2)-      (Just _, Nothing) -> iter 1-      (Nothing, _)      -> iter 2-{-# INLINE mergeByChunks #-}---- --------------------------------------------------------------------------- Folds---- | Left-associative fold that is strict in the accumulator.--- This function should be used in preference to 'foldl' whenever possible.------ The analogue of @List.foldl'@.-foldStream-  :: LL.ListLike s el-  => (a -> el -> a)-  -> a-  -> Iteratee s m a-foldStream f i = liftI (step i)-  where-    step acc (Chunk xs)-      | LL.null xs = liftI (step acc)-      | otherwise  = liftI (step $! FLL.foldl' f acc xs)-    step acc stream = idone acc stream-{-# INLINE foldStream #-}---- --------------------------------------------------------------------------- Zips---- |Enumerate two iteratees over a single stream simultaneously.------ Compare to @List.zip@.-zipStreams-  :: (Monad m, Nullable s, LL.ListLike s el)-  => Iteratee s m a-  -> Iteratee s m b-  -> Iteratee s m (a, b)-zipStreams x0 y0 = do-    -- need to check if both iteratees are initially finished.  If so,-    -- we don't want to push a chunk which will be dropped-    (a', x') <- lift $ runIter x0 od oc-    (b', y') <- lift $ runIter y0 od oc-    case checkDone a' b' of-      Just (Right (a,b,s))  -> idone (a,b) s  -- 's' may be EOF, needs to stay-      Just (Left (Left a))  -> liftM (a,) y'-      Just (Left (Right b)) -> liftM (,b) x'-      Nothing               -> liftI (step x' y')-  where-    step x y (Chunk xs) | nullC xs = liftI (step x y)-    step x y (Chunk xs) = do-      (a', x') <- lift $ (\i -> runIter i od oc) =<< enumPure1Chunk xs x-      (b', y') <- lift $ (\i -> runIter i od oc) =<< enumPure1Chunk xs y-      case checkDone a' b' of-        Just (Right (a,b,s))  -> idone (a,b) s-        Just (Left (Left a))  -> liftM (a,) y'-        Just (Left (Right b)) -> liftM (,b) x'-        Nothing               -> liftI (step x' y')-    step x y (EOF err) = joinIM $ case err of-      Nothing -> (liftM2.liftM2) (,) (enumEof   x) (enumEof   y)-      Just e  -> (liftM2.liftM2) (,) (enumErr e x) (enumErr e y)--    od a s = return (Just (a, s), idone a s)-    oc k e = return (Nothing    , icont k e)--    checkDone r1 r2 = case (r1, r2) of-      (Just (a, s1), Just (b,s2)) -> Just $ Right (a, b, shorter s1 s2)-      (Just (a, _), Nothing)      -> Just . Left $ Left a-      (Nothing, Just (b, _))      -> Just . Left $ Right b-      (Nothing, Nothing)          -> Nothing--    shorter c1@(Chunk xs) c2@(Chunk ys)-      | LL.length xs < LL.length ys = c1-      | otherwise                   = c2-    shorter e@(EOF _)  _         = e-    shorter _          e@(EOF _) = e-{-# INLINE zipStreams #-}--zipStreams3-  :: (Monad m, Nullable s, LL.ListLike s el)-  => Iteratee s m a -> Iteratee s m b-  -> Iteratee s m c -> Iteratee s m (a, b, c)-zipStreams3 a b c = zipStreams a (zipStreams b c) >>=-  \(r1, (r2, r3)) -> return (r1, r2, r3)-{-# INLINE zipStreams3 #-}--zipStreams4-  :: (Monad m, Nullable s, LL.ListLike s el)-  => Iteratee s m a -> Iteratee s m b-  -> Iteratee s m c -> Iteratee s m d-  -> Iteratee s m (a, b, c, d)-zipStreams4 a b c d = zipStreams a (zipStreams3 b c d) >>=-  \(r1, (r2, r3, r4)) -> return (r1, r2, r3, r4)-{-# INLINE zipStreams4 #-}--zipStreams5-  :: (Monad m, Nullable s, LL.ListLike s el)-  => Iteratee s m a -> Iteratee s m b-  -> Iteratee s m c -> Iteratee s m d-  -> Iteratee s m e -> Iteratee s m (a, b, c, d, e)-zipStreams5 a b c d e = zipStreams a (zipStreams4 b c d e) >>=-  \(r1, (r2, r3, r4, r5)) -> return (r1, r2, r3, r4, r5)-{-# INLINE zipStreams5 #-}---- | Enumerate over two iteratees in parallel as long as the first iteratee--- is still consuming input.  The second iteratee will be terminated with EOF--- when the first iteratee has completed.  An example use is to determine--- how many elements an iteratee has consumed:------ > snd <$> enumWith (dropWhile (<5)) length------ Compare to @zipStreams@-enumWith-  :: (Monad m, Nullable s, LL.ListLike s el)-  => Iteratee s m a-  -> Iteratee s m b-  -> Iteratee s m (a, b)-enumWith i1 i2 = do-    -- as with zipStreams, first check to see if the initial iteratee is complete,-    -- otherwise data would be dropped.-    -- running the second iteratee as well to prevent a monadic effect mismatch-    -- although I think that would be highly unlikely to happen in common-    -- code-    (a', x') <- lift $ runIter i1 od oc-    (_,  y') <- lift $ runIter i2 od oc-    case a' of-      Just (a, s) -> flip idone s =<< lift (liftM (a,) $ run i2)-      Nothing     -> go x' y'-  where-    od a s = return (Just (a, s), idone a s)-    oc k e = return (Nothing    , icont k e)--    getUsed xs (Chunk ys) = LL.take (LL.length xs - LL.length ys) xs-    getUsed xs (EOF _)    = xs--    go x y = liftI step-      where-        step (Chunk xs) | nullC xs = liftI step-        step (Chunk xs) = do-          (a', x') <- lift $ (\i -> runIter i od oc) =<< enumPure1Chunk xs x-          case a' of-            Just (a, s) -> do-              b <- lift $ run =<< enumPure1Chunk (getUsed xs s) y-              idone (a, b) s-            Nothing        -> lift (enumPure1Chunk xs y) >>= go x'-        step (EOF err) = joinIM $ case err of-          Nothing -> (liftM2.liftM2) (,) (enumEof   x) (enumEof   y)-          Just e  -> (liftM2.liftM2) (,) (enumErr e x) (enumErr e y)-{-# INLINE enumWith #-}---- |Enumerate a list of iteratees over a single stream simultaneously--- and discard the results. This is a different behavior than Prelude's--- sequence_ which runs iteratees in the list one after the other.------ Compare to @Prelude.sequence_@.-sequenceStreams_-  :: (Monad m, LL.ListLike s el, Nullable s)-  => [Iteratee s m a]-  -> Iteratee s m ()-sequenceStreams_ = self-  where-    self is = liftI step-      where-        step (Chunk xs) | LL.null xs = liftI step-        step s@(Chunk _) = do-          -- give a chunk to each iteratee-          is'  <- lift $ mapM (enumChunk s) is-          -- filter done iteratees-          (done, notDone) <- lift $ partition fst `liftM` mapM enumCheckIfDone is'-          if null notDone-            then idone () <=< remainingStream $ map snd done-            else self $ map snd notDone-        step s@(EOF _) = do-          s' <- remainingStream <=< lift $ mapM (enumChunk s) is-          case s' of-            EOF (Just e) -> throwErr e-            _            -> idone () s'--    -- returns the unconsumed part of the stream; "sequenceStreams_ is" consumes as-    -- much of the stream as the iteratee in is that consumes the most; e.g.-    -- sequenceStreams_ [I.head, I.last] consumes whole stream-    remainingStream-      :: (Monad m, Nullable s, LL.ListLike s el)-      => [Iteratee s m a] -> Iteratee s m (Stream s)-    remainingStream is = lift $-      return . foldl1 shorter <=< mapM (\i -> runIter i od oc) $ is-      where-        od _ s = return s-        oc _ e = return $ case e of-          Nothing -> mempty-          _       -> EOF e--    -- return the shorter one of two streams; errors are propagated with the-    -- priority given to the "left"-    shorter c1@(Chunk xs) c2@(Chunk ys)-      | LL.length xs < LL.length ys = c1-      | otherwise                   = c2-    shorter (EOF e1 ) (EOF e2 ) = EOF (e1 `mplus` e2)-    shorter e@(EOF _) _         = e-    shorter _         e@(EOF _) = e---- |Transform an iteratee into one that keeps track of how much data it--- consumes.-countConsumed :: forall a s el m n.-                 (Monad m, LL.ListLike s el, Nullable s, Integral n) =>-                 Iteratee s m a-              -> Iteratee s m (a, n)-countConsumed i = go 0 (const i) (Chunk emptyP)-  where-    go :: n -> (Stream s -> Iteratee s m a) -> Stream s-       -> Iteratee s m (a, n)-    go !n f str@(EOF _) = (, n) `liftM` f str-    go !n f str@(Chunk c) = Iteratee rI-      where-        newLen = n + fromIntegral (LL.length c)-        rI od oc = runIter (f str) onDone onCont-          where-            onDone a str'@(Chunk c') =-                od (a, newLen - fromIntegral (LL.length c')) str'-            onDone a str'@(EOF _) = od (a, n) str'-            onCont f' mExc = oc (go newLen f') mExc-{-# INLINE countConsumed #-}---- --------------------------------------------------------------------------- Enumerators---- |The pure n-chunk enumerator--- It passes a given stream of elements to the iteratee in @n@-sized chunks.-enumPureNChunk :: (Monad m, LL.ListLike s el) => s -> Int -> Enumerator s m a-enumPureNChunk str n iter-  | LL.null str = return iter-  | n > 0       = enum' str iter-  | otherwise   = error $ "enumPureNChunk called with n==" ++ show n-  where-    enum' str' iter'-      | LL.null str' = return iter'-      | otherwise    = let (s1, s2) = LL.splitAt n str'-                           on_cont k Nothing = enum' s2 . k $ Chunk s1-                           on_cont k e = return $ icont k e-                       in runIter iter' idoneM on_cont-{-# INLINE enumPureNChunk #-}---- --------------------------------------------------------------------------- Monadic functions---- | Map a monadic function over the elements of the stream and ignore the--- result.-mapStreamM_ :: (Monad m, Nullable s, LL.ListLike s el) => (el -> m b) -> Iteratee s m ()-mapStreamM_ = mapChunksM_ . LL.mapM_-{-# INLINE mapStreamM_ #-}---- | Map a monadic function over an 'Iteratee'.-mapStreamM :: (Monad m, LL.ListLike (s el) el, LL.ListLike (s el') el', NullPoint (s el))-           => (el -> m el') -> Enumeratee (s el) (s el') m a-mapStreamM = mapChunksM . LL.mapM-{-# INLINE mapStreamM #-}----- | Fold a monadic function over an 'Iteratee'.-foldStreamM :: (Monad m, Nullable s, LL.ListLike s a) => (b -> a -> m b) -> b -> Iteratee s m b-foldStreamM k = foldChunksM go-  where-    go b s | LL.null s = return b-           | otherwise = k b (LL.head s) >>= \b' -> go b' (LL.tail s)-{-# INLINE foldStreamM #-}
− src/Bio/Iteratee/ReadableChunk.hs
@@ -1,49 +0,0 @@-{-# LANGUAGE FunctionalDependencies #-}---- | Monadic Iteratees:--- incremental input parsers, processors and transformers------ Support for IO enumerators--module Bio.Iteratee.ReadableChunk ( ReadableChunk(..) ) where--import Control.Monad.IO.Class-import Data.Word-import Foreign.C-import Foreign.Marshal.Array-import Foreign.Ptr-import Foreign.Storable-import Prelude--import qualified Data.ByteString      as B-import qualified Data.ByteString.Lazy as L---- |Class of streams which can be filled from a 'Ptr'.  Typically these--- are streams which can be read from a file, @Handle@, or similar resource.-------class (Storable el) => ReadableChunk s el | s -> el where-  readFromPtr ::-    MonadIO m =>-      Ptr el-      -> Int -- ^ The pointer must not be used after @readFromPtr@ completes.-      -> m s -- ^ The Int parameter is the length of the data in *bytes*.--instance ReadableChunk [Char] Char where-  readFromPtr buf l = liftIO $ peekCAStringLen (castPtr buf, l)--instance ReadableChunk [Word8] Word8 where-  readFromPtr buf l = liftIO $ peekArray l buf-instance ReadableChunk [Word16] Word16 where-  readFromPtr buf l = liftIO $ peekArray l buf-instance ReadableChunk [Word32] Word32 where-  readFromPtr buf l = liftIO $ peekArray l buf-instance ReadableChunk [Word] Word where-  readFromPtr buf l = liftIO $ peekArray l buf--instance ReadableChunk B.ByteString Word8 where-  readFromPtr buf l = liftIO $ B.packCStringLen (castPtr buf, l)--instance ReadableChunk L.ByteString Word8 where-  readFromPtr buf l = liftIO $-    return . L.fromChunks . (:[]) =<< readFromPtr buf l
src/Bio/Iteratee/ZLib.hsc view
@@ -713,7 +713,7 @@  -- | Inflate if Gzip format is recognized, otherwise pass through. enumInflateAny :: MonadIO m => Enumeratee ByteString ByteString m a-enumInflateAny it = do magic <- iLookAhead $ liftM2 (,) tryHead tryHead+enumInflateAny it = do magic <- iLookAhead $ liftM2 (,) tryHeadBS tryHeadBS                        case magic of                            (Just 0x1f, Just 0x8b) ->                                enumInflate GZip defaultDecompressParams it
src/Bio/Prelude.hs view
@@ -6,6 +6,13 @@     module System.Posix.Files,     module System.Posix.IO,     module System.Posix.Types,+#if !MIN_VERSION_base_prelude(1,1,0)+    module Foreign.Storable,+    module Foreign.Ptr,+    module Foreign.ForeignPtr,+    module Foreign.StablePtr,+#endif+     Bytes, LazyBytes,     HashMap,     HashSet,@@ -63,11 +70,17 @@ import Data.IntSet         ( IntSet ) import Data.Text.Encoding  ( encodeUtf8, decodeUtf8With ) import Foreign.C.Error     ( throwErrnoIf_ )-import Foreign.Ptr         ( castPtr ) import System.IO           ( hPrint, hPutStr, hPutStrLn, stderr, stdout, stdin ) import System.Posix.Files import System.Posix.IO import System.Posix.Types++#if !MIN_VERSION_base_prelude(1,1,0)+import Foreign.Storable+import Foreign.Ptr+import Foreign.ForeignPtr+import Foreign.StablePtr+#endif  import qualified Data.ByteString.Unsafe as B import qualified Data.ByteString.Lazy   as BL
− src/Bio/PriorityQueue.hs
@@ -1,142 +0,0 @@-module Bio.PriorityQueue (-        Sizeable(..),-        PQ_Conf(..),--        PQ,-        withPQ,-        makePQ,-        deletePQ,-        enqueuePQ,-        dequeuePQ,-        getMinPQ,-        peekMinPQ,-        sizePQ-) where--import Data.Binary-import Data.IORef-import qualified Control.Exception as CE-import Prelude---- | A Priority Queue that can fall back to external storage.------ Note that such a Priority Queue automatically gives rise to an--- external sorting algorithm:  enqueue everything, dequeue until empty.------ Whatever is to be stored in this queue needs to be in Binary, because--- it may need to be moved to external storage on demand.  We also need--- a way to estimate the memory consumption of an enqueued object.  When--- constructing the queue, the maximum amount of RAM to consume is set.--- Note that open input streams use memory for buffering, too.------ Enqueued objects are kept in an in memory heap until the memory--- consumption becomes too high.  At that point, the whole heap is--- sorted and dumped to external storage.  If necessary, the file to do--- so is created and kept open.  The newly created stream is added to a--- heap so that dequeueing objects amounts to performing a merge sort on--- multiple external streams.  To conserve on file descriptors, we--- concatenate multiple streams into a single file, then use pread(2) on--- that as appropriate.  If too many streams are open (how do we set--- that limit?), we do exactly that:  merge-sort all streams and the--- in-memory heap into a single new stream.  One file is created for--- each generation of streams, so that mergind handles streams of--- roughly equal length.------ XXX  Truth be told, this queue isn't backed externally, and ignores---      all limits.  It *is* a Priority Queue, though!------ XXX  May want to add callbacks for significant events (new file,---      massive merge, deletion of file?)------ XXX  Need to track memory consumption of input buffers.------ XXX  Need a way to decide when too many streams are open.  That point---      is reached when seeking takes about as much time as reading---      (which depends on buffer size and system characteristics), so---      that an additional merge pass becomes economical.------ XXX  These will be useful:---          unix-bytestring:System.Posix.IO.ByteString.fdPread---          temporary:System.IO.Temp.openBinaryTempFile---          lz4:Codec.Compression.LZ4--data PQ_Conf = PQ_Conf {-        max_mb :: Int,          -- ^ memory limit-        temp_path :: FilePath   -- ^ path to temporary files (a directory will be created)-        -- functions to report progress go here-    }--newtype PQ a = PQ (IORef (SkewHeap a, Int))--class Sizeable a where usedBytes :: a -> Int---- | Creates a priority queue.  Note that the priority queue creates--- files, which will only be cleaned up if deletePQ is called.-makePQ :: (Binary a, Ord a, Sizeable a) => PQ_Conf -> IO (PQ a)-makePQ _ = PQ `fmap` newIORef (Empty,0)---- | Deletes the priority queue and all associated temporary files.-deletePQ :: PQ a -> IO ()-deletePQ (PQ _) = return ()--withPQ :: (Binary a, Ord a, Sizeable a) => PQ_Conf -> (PQ a -> IO b) -> IO b-withPQ conf = CE.bracket (makePQ conf) deletePQ---- | Enqueues an element.--- This operation may result in the creation of a file or in an enormous--- merge of already created files.-enqueuePQ :: (Binary a, Ord a, Sizeable a) => a -> PQ a -> IO ()-enqueuePQ a (PQ pq) = do (p,s) <- readIORef pq-                         let !p' = insert a p-                             !s' = 1 + s-                         writeIORef pq (p',s')---- | Removes the minimum element from the queue.--- If the queue is already empty, nothing happens.  As a result, it is--- possible that one or more file become empty and are deleted.-dequeuePQ :: (Binary a, Ord a, Sizeable a ) => PQ a -> IO ()-dequeuePQ (PQ pq) = do (p,s) <- readIORef pq-                       let !p' = dropMin p-                           !s' = max 0 (s - 1)-                       writeIORef pq (p',s')----- | Returns the minimum element from the queue.--- If the queue is empty, Nothing is returned.  Else the minimum element--- currently in the queue.-peekMinPQ :: (Binary a, Ord a, Sizeable a) => PQ a -> IO (Maybe a)-peekMinPQ (PQ pq) = (getMin . fst) `fmap` readIORef pq--getMinPQ :: (Binary a, Ord a, Sizeable a) => PQ a -> IO (Maybe a)-getMinPQ (PQ pq) = do r <- (getMin . fst) `fmap` readIORef pq-                      case r of Nothing -> return () ; Just _ -> dequeuePQ  (PQ pq)-                      return r--sizePQ :: (Binary a, Ord a, Sizeable a) => PQ a -> IO Int-sizePQ (PQ pq) = snd `fmap` readIORef pq----- We need an in-memory heap anyway.  Here's a skew heap.-data SkewHeap a = Empty | Node a (SkewHeap a) (SkewHeap a)--singleton :: a -> SkewHeap a-singleton x = Node x Empty Empty--union :: Ord a => SkewHeap a -> SkewHeap a -> SkewHeap a-Empty              `union` t2                 = t2-t1                 `union` Empty              = t1-t1@(Node x1 l1 r1) `union` t2@(Node x2 l2 r2)-   | x1 <= x2                                 = Node x1 (t2 `union` r1) l1-   | otherwise                                = Node x2 (t1 `union` r2) l2--insert :: Ord a => a -> SkewHeap a -> SkewHeap a-insert x heap = singleton x `union` heap--getMin :: SkewHeap a -> Maybe a-getMin Empty        = Nothing-getMin (Node x _ _) = Just x--dropMin :: Ord a => SkewHeap a -> SkewHeap a-dropMin Empty        = error "dropMin on empty queue... are you sure?!"-dropMin (Node _ l r) = l `union` r-
src/cbits/loops.c view
@@ -18,6 +18,18 @@     } } +void nuc_loop_wide( char* p, int stride, char* q, int u, int v )+{+    u *= stride ;+    v *= stride ;++    while( u < v ) {+        char a = q[ u ] ;+        *p++ = a ? 0x1 << (a&3) : 0xf  ;+        u += stride ;+    }+}+ void nuc_loop_asc( char* p, int stride, char* q, int u, int v ) {     u *= stride ;