1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE ExistentialQuantification #-}
5{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE PatternSynonyms #-}
9{-# LANGUAGE RecordWildCards #-}
10{-# LANGUAGE ScopedTypeVariables #-}
11{-# LANGUAGE ViewPatterns #-}
12{-# LANGUAGE RankNTypes #-}
13{-# LANGUAGE MagicHash #-}
18-- Module : Streamly.Streams.StreamD
19-- Copyright : (c) 2018 Harendra Kumar
20-- Copyright : (c) Roman Leshchinskiy 2008-2010
23-- Maintainer : harendra.kumar@gmail.com
24-- Stability : experimental
27-- Direct style re-implementation of CPS style stream in StreamK module. The
28-- symbol or suffix 'D' in this module denotes the "Direct" style. GHC is able
29-- to INLINE and fuse direct style better, providing better performance than
33-- import qualified Streamly.Streams.StreamD as D
36-- Some of the functions in this file have been adapted from the vector
37-- library, https://hackage.haskell.org/package/vector.
39module Streamly.Streams.StreamD
57 -- ** Specialized Generation
58 -- | Generate a monadic stream from a seed.
68 , enumerateFromStepIntegral
69 , enumerateFromIntegral
70 , enumerateFromThenIntegral
71 , enumerateFromToIntegral
72 , enumerateFromThenToIntegral
74 , enumerateFromStepNum
77 , enumerateFromToFractional
78 , enumerateFromThenToFractional
81 -- | Transform an input structure into a stream.
82 -- | Direct style stream does not support @fromFoldable@.
109 -- ** Specialized Folds
130 -- ** Flattening nested streams
157 -- | Transform a stream into another type.
166 -- ** By folding (scans)
232 -- * Transformation comprehensions
243 -- * UTF8 Encoding / Decoding transformations.
249import Control.Exception (Exception)
250import Control.Monad.Catch (MonadCatch)
251import Control.Monad.IO.Class (MonadIO(..))
252import Control.Monad.Trans (MonadTrans(lift))
253import Data.Bits (shiftR, shiftL, (.|.), (.&.))
254import Data.Maybe (fromJust, isJust)
255import Data.Word (Word32)
256import Foreign.Ptr (Ptr)
257import Foreign.Storable (Storable(..))
258import GHC.Base (assert, Char(..), unsafeChr, (-#), (+#), uncheckedIShiftL#,
259 word2Int#, chr#, ord)
260import GHC.IO.Encoding.Failure (isSurrogate)
261import GHC.Types (SPEC(..))
262import GHC.Word (Word8(..))
264 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
265 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
266 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
267 (!!), scanl, scanl1, concatMap, replicate, enumFromTo, concat,
270import qualified Control.Monad.Catch as MC
272import Streamly.Mem.Array.Types (Array(..))
273import Streamly.Fold.Types (Fold(..))
274import Streamly.Pipe.Types (Pipe(..), PipeState(..))
275import Streamly.SVar (MonadAsync, defState, adaptState)
276import Streamly.Sink.Types (Sink(..))
278import Streamly.Streams.StreamD.Type
280import qualified Streamly.Pipe.Types as Pipe
281import qualified Streamly.Mem.Array.Types as A
282import qualified Streamly.Mem.Ring as RB
283import qualified Streamly.Streams.StreamK as K
285------------------------------------------------------------------------------
287------------------------------------------------------------------------------
289-- | An empty 'Stream'.
290{-# INLINE_NORMAL nil #-}
291nil :: Monad m => Stream m a
292nil = Stream (\_ _ -> return Stop) ()
294{-# INLINE_NORMAL consM #-}
295consM :: Monad m => m a -> Stream m a -> Stream m a
296consM m (Stream step state) = Stream step1 Nothing
298 {-# INLINE_LATE step1 #-}
299 step1 _ Nothing = m >>= \x -> return $ Yield x (Just state)
300 step1 gst (Just st) = do
304 Yield a s -> Yield a (Just s)
305 Skip s -> Skip (Just s)
308-- XXX implement in terms of consM?
309-- cons x = consM (return x)
311-- | Can fuse but has O(n^2) complexity.
312{-# INLINE_NORMAL cons #-}
313cons :: Monad m => a -> Stream m a -> Stream m a
314cons x (Stream step state) = Stream step1 Nothing
316 {-# INLINE_LATE step1 #-}
317 step1 _ Nothing = return $ Yield x (Just state)
318 step1 gst (Just st) = do
322 Yield a s -> Yield a (Just s)
323 Skip s -> Skip (Just s)
326-------------------------------------------------------------------------------
328-------------------------------------------------------------------------------
330-- Does not fuse, has the same performance as the StreamK version.
331{-# INLINE_NORMAL uncons #-}
332uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
333uncons (UnStream step state) = go state
336 r <- step defState st
338 Yield x s -> return $ Just (x, Stream step s)
340 Stop -> return Nothing
342------------------------------------------------------------------------------
343-- Generation by unfold
344------------------------------------------------------------------------------
346{-# INLINE_NORMAL unfoldrM #-}
347unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
348unfoldrM next state = Stream step state
350 {-# INLINE_LATE step #-}
354 Just (x, s) -> Yield x s
357{-# INLINE_LATE unfoldr #-}
358unfoldr :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a
359unfoldr f = unfoldrM (return . f)
361------------------------------------------------------------------------------
362-- Specialized Generation
363------------------------------------------------------------------------------
365repeat :: Monad m => a -> Stream m a
366repeat x = Stream (\_ _ -> return $ Yield x ()) ()
368{-# INLINE_NORMAL replicateM #-}
369replicateM :: Monad m => Int -> m a -> Stream m a
370replicateM n p = Stream step n
372 {-# INLINE_LATE step #-}
373 step _ i | i <= 0 = return Stop
376 return $ Yield x (i - 1)
378{-# INLINE_NORMAL replicate #-}
379replicate :: Monad m => Int -> a -> Stream m a
380replicate n x = replicateM n (return x)
382-- This would not work properly for floats, therefore we put an Integral
384-- | Can be used to enumerate unbounded integrals. This does not check for
385-- overflow or underflow for bounded integrals.
386{-# INLINE_NORMAL enumerateFromStepIntegral #-}
387enumerateFromStepIntegral :: (Integral a, Monad m) => a -> a -> Stream m a
388enumerateFromStepIntegral from stride =
389 from `seq` stride `seq` Stream step from
391 {-# INLINE_LATE step #-}
392 step _ !x = return $ Yield x $! (x + stride)
394-- We are assuming that "to" is constrained by the type to be within
396{-# INLINE enumerateFromToIntegral #-}
397enumerateFromToIntegral :: (Monad m, Integral a) => a -> a -> Stream m a
398enumerateFromToIntegral from to =
399 takeWhile (<= to) $ enumerateFromStepIntegral from 1
401{-# INLINE enumerateFromIntegral #-}
402enumerateFromIntegral :: (Monad m, Integral a, Bounded a) => a -> Stream m a
403enumerateFromIntegral from = enumerateFromToIntegral from maxBound
405data EnumState a = EnumInit | EnumYield a a a | EnumStop
407{-# INLINE_NORMAL enumerateFromThenToIntegralUp #-}
408enumerateFromThenToIntegralUp
409 :: (Monad m, Integral a)
410 => a -> a -> a -> Stream m a
411enumerateFromThenToIntegralUp from next to = Stream step EnumInit
413 {-# INLINE_LATE step #-}
419 else Yield from EnumStop
420 else -- from <= next <= to
421 let stride = next - from
422 in Skip $ EnumYield from stride (to - stride)
424 step _ (EnumYield x stride toMinus) =
427 then Yield x EnumStop
428 else Yield x $ EnumYield (x + stride) stride toMinus
430 step _ EnumStop = return Stop
432{-# INLINE_NORMAL enumerateFromThenToIntegralDn #-}
433enumerateFromThenToIntegralDn
434 :: (Monad m, Integral a)
435 => a -> a -> a -> Stream m a
436enumerateFromThenToIntegralDn from next to = Stream step EnumInit
438 {-# INLINE_LATE step #-}
440 return $ if to > next
443 else Yield from EnumStop
444 else -- from >= next >= to
445 let stride = next - from
446 in Skip $ EnumYield from stride (to - stride)
448 step _ (EnumYield x stride toMinus) =
451 then Yield x EnumStop
452 else Yield x $ EnumYield (x + stride) stride toMinus
454 step _ EnumStop = return Stop
456{-# INLINE_NORMAL enumerateFromThenToIntegral #-}
457enumerateFromThenToIntegral
458 :: (Monad m, Integral a)
459 => a -> a -> a -> Stream m a
460enumerateFromThenToIntegral from next to
461 | next >= from = enumerateFromThenToIntegralUp from next to
462 | otherwise = enumerateFromThenToIntegralDn from next to
464{-# INLINE_NORMAL enumerateFromThenIntegral #-}
465enumerateFromThenIntegral
466 :: (Monad m, Integral a, Bounded a)
467 => a -> a -> Stream m a
468enumerateFromThenIntegral from next =
470 then enumerateFromThenToIntegralUp from next maxBound
471 else enumerateFromThenToIntegralDn from next minBound
473-- For floating point numbers if the increment is less than the precision then
474-- it just gets lost. Therefore we cannot always increment it correctly by just
476-- 9007199254740992 + 1 + 1 :: Double => 9.007199254740992e15
477-- 9007199254740992 + 2 :: Double => 9.007199254740994e15
479-- Instead we accumulate the increment counter and compute the increment
480-- everytime before adding it to the starting number.
482-- This works for Integrals as well as floating point numbers, but
483-- enumerateFromStepIntegral is faster for integrals.
484{-# INLINE_NORMAL enumerateFromStepNum #-}
485enumerateFromStepNum :: (Monad m, Num a) => a -> a -> Stream m a
486enumerateFromStepNum from stride = Stream step 0
488 {-# INLINE_LATE step #-}
489 step _ !i = return $ (Yield $! (from + i * stride)) $! (i + 1)
491{-# INLINE_NORMAL numFrom #-}
492numFrom :: (Monad m, Num a) => a -> Stream m a
493numFrom from = enumerateFromStepNum from 1
495{-# INLINE_NORMAL numFromThen #-}
496numFromThen :: (Monad m, Num a) => a -> a -> Stream m a
497numFromThen from next = enumerateFromStepNum from (next - from)
499-- We cannot write a general function for Num. The only way to write code
500-- portable between the two is to use a 'Real' constraint and convert between
501-- Fractional and Integral using fromRational which is horribly slow.
502{-# INLINE_NORMAL enumerateFromToFractional #-}
503enumerateFromToFractional
504 :: (Monad m, Fractional a, Ord a)
505 => a -> a -> Stream m a
506enumerateFromToFractional from to =
507 takeWhile (<= to + 1 / 2) $ enumerateFromStepNum from 1
509{-# INLINE_NORMAL enumerateFromThenToFractional #-}
510enumerateFromThenToFractional
511 :: (Monad m, Fractional a, Ord a)
512 => a -> a -> a -> Stream m a
513enumerateFromThenToFractional from next to =
514 takeWhile predicate $ numFromThen from next
516 mid = (next - from) / 2
517 predicate | next >= from = (<= to + mid)
518 | otherwise = (>= to + mid)
520-------------------------------------------------------------------------------
521-- Generation by Conversion
522-------------------------------------------------------------------------------
524{-# INLINE_NORMAL fromIndicesM #-}
525fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
526fromIndicesM gen = Stream step 0
528 {-# INLINE_LATE step #-}
531 return $ Yield x (i + 1)
533{-# INLINE fromIndices #-}
534fromIndices :: Monad m => (Int -> a) -> Stream m a
535fromIndices gen = fromIndicesM (return . gen)
537{-# INLINE_NORMAL generateM #-}
538generateM :: Monad m => Int -> (Int -> m a) -> Stream m a
539generateM n gen = n `seq` Stream step 0
541 {-# INLINE_LATE step #-}
542 step _ i | i < n = do
544 return $ Yield x (i + 1)
545 | otherwise = return Stop
547{-# INLINE generate #-}
548generate :: Monad m => Int -> (Int -> a) -> Stream m a
549generate n gen = generateM n (return . gen)
551-- XXX we need the MonadAsync constraint because of a rewrite rule.
552-- | Convert a list of monadic actions to a 'Stream'
553{-# INLINE_LATE fromListM #-}
554fromListM :: MonadAsync m => [m a] -> Stream m a
555fromListM = Stream step
557 {-# INLINE_LATE step #-}
558 step _ (m:ms) = m >>= \x -> return $ Yield x ms
559 step _ [] = return Stop
561{-# INLINE toStreamD #-}
562toStreamD :: (K.IsStream t, Monad m) => t m a -> Stream m a
563toStreamD = fromStreamK . K.toStream
565------------------------------------------------------------------------------
566-- Elimination by Folds
567------------------------------------------------------------------------------
569------------------------------------------------------------------------------
571------------------------------------------------------------------------------
573{-# INLINE_NORMAL foldr1 #-}
574foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
578 Nothing -> return Nothing
579 Just (h, t) -> fmap Just (foldr f h t)
581------------------------------------------------------------------------------
583------------------------------------------------------------------------------
585{-# INLINE_NORMAL foldlT #-}
586foldlT :: (Monad m, Monad (s m), MonadTrans s)
587 => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
588foldlT fstep begin (Stream step state) = go SPEC begin state
591 r <- lift $ step defState st
593 Yield x s -> go SPEC (fstep acc x) s
594 Skip s -> go SPEC acc s
597-- Note, this is going to have horrible performance, because of the nature of
598-- the stream type (i.e. direct stream vs CPS). Its only for reference, it is
599-- likely be practically unusable.
600{-# INLINE_NORMAL foldlS #-}
602 => (Stream m b -> a -> Stream m b) -> Stream m b -> Stream m a -> Stream m b
603foldlS fstep begin (Stream step state) = Stream step' (Left (state, begin))
605 step' gst (Left (st, acc)) = do
606 r <- step (adaptState gst) st
608 Yield x s -> Skip (Left (s, fstep acc x))
609 Skip s -> Skip (Left (s, acc))
610 Stop -> Skip (Right acc)
612 step' gst (Right (Stream stp stt)) = do
613 r <- stp (adaptState gst) stt
615 Yield x s -> Yield x (Right (Stream stp s))
616 Skip s -> Skip (Right (Stream stp s))
619------------------------------------------------------------------------------
621------------------------------------------------------------------------------
623-- | Run a streaming composition, discard the results.
624{-# INLINE_LATE drain #-}
625drain :: Monad m => Stream m a -> m ()
626-- drain m = foldrM (\x xs -> x `seq` xs) (return ()) m
627drain (Stream step state) = go SPEC state
630 r <- step defState st
632 Yield _ s -> go SPEC s
636{-# INLINE_NORMAL null #-}
637null :: Monad m => Stream m a -> m Bool
638null m = foldrM (\_ _ -> return False) (return True) m
641{-# INLINE_NORMAL head #-}
642head :: Monad m => Stream m a -> m (Maybe a)
643head m = foldrM (\x _ -> return (Just x)) (return Nothing) m
645-- Does not fuse, has the same performance as the StreamK version.
646{-# INLINE_NORMAL tail #-}
647tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
648tail (UnStream step state) = go state
651 r <- step defState st
653 Yield _ s -> return (Just $ Stream step s)
655 Stop -> return Nothing
657-- XXX will it fuse? need custom impl?
658{-# INLINE_NORMAL last #-}
659last :: Monad m => Stream m a -> m (Maybe a)
660last = foldl' (\_ y -> Just y) Nothing
662{-# INLINE_NORMAL elem #-}
663elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
664-- elem e m = foldrM (\x xs -> if x == e then return True else xs) (return False) m
665elem e (Stream step state) = go state
668 r <- step defState st
671 | x == e -> return True
676{-# INLINE_NORMAL notElem #-}
677notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
678notElem e s = fmap not (elem e s)
680{-# INLINE_NORMAL all #-}
681all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
682-- all p m = foldrM (\x xs -> if p x then xs else return False) (return True) m
683all p (Stream step state) = go state
686 r <- step defState st
690 | otherwise -> return False
694{-# INLINE_NORMAL any #-}
695any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
696-- any p m = foldrM (\x xs -> if p x then return True else xs) (return False) m
697any p (Stream step state) = go state
700 r <- step defState st
708{-# INLINE_NORMAL maximum #-}
709maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
710maximum (Stream step state) = go Nothing state
713 r <- step defState st
715 Yield x s -> go (Just x) s
716 Skip s -> go Nothing s
717 Stop -> return Nothing
718 go (Just acc) st = do
719 r <- step defState st
722 | acc <= x -> go (Just x) s
723 | otherwise -> go (Just acc) s
724 Skip s -> go (Just acc) s
725 Stop -> return (Just acc)
727{-# INLINE_NORMAL maximumBy #-}
728maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
729maximumBy cmp (Stream step state) = go Nothing state
732 r <- step defState st
734 Yield x s -> go (Just x) s
735 Skip s -> go Nothing s
736 Stop -> return Nothing
737 go (Just acc) st = do
738 r <- step defState st
740 Yield x s -> case cmp acc x of
741 GT -> go (Just acc) s
743 Skip s -> go (Just acc) s
744 Stop -> return (Just acc)
746{-# INLINE_NORMAL minimum #-}
747minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
748minimum (Stream step state) = go Nothing state
751 r <- step defState st
753 Yield x s -> go (Just x) s
754 Skip s -> go Nothing s
755 Stop -> return Nothing
756 go (Just acc) st = do
757 r <- step defState st
760 | acc <= x -> go (Just acc) s
761 | otherwise -> go (Just x) s
762 Skip s -> go (Just acc) s
763 Stop -> return (Just acc)
765{-# INLINE_NORMAL minimumBy #-}
766minimumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
767minimumBy cmp (Stream step state) = go Nothing state
770 r <- step defState st
772 Yield x s -> go (Just x) s
773 Skip s -> go Nothing s
774 Stop -> return Nothing
775 go (Just acc) st = do
776 r <- step defState st
778 Yield x s -> case cmp acc x of
781 Skip s -> go (Just acc) s
782 Stop -> return (Just acc)
784{-# INLINE_NORMAL (!!) #-}
785(!!) :: (Monad m) => Stream m a -> Int -> m (Maybe a)
786(Stream step state) !! i = go i state
789 r <- step defState st
791 Yield x s | n < 0 -> return Nothing
792 | n == 0 -> return $ Just x
793 | otherwise -> go (n - 1) s
795 Stop -> return Nothing
797{-# INLINE_NORMAL lookup #-}
798lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
799lookup e m = foldrM (\(a, b) xs -> if e == a then return (Just b) else xs)
802{-# INLINE_NORMAL findM #-}
803findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
804findM p m = foldrM (\x xs -> p x >>= \r -> if r then return (Just x) else xs)
808find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
809find p = findM (return . p)
811{-# INLINE_NORMAL findIndices #-}
812findIndices :: Monad m => (a -> Bool) -> Stream m a -> Stream m Int
813findIndices p (Stream step state) = Stream step' (state, 0)
815 {-# INLINE_LATE step' #-}
816 step' gst (st, i) = do
817 r <- step (adaptState gst) st
819 Yield x s -> if p x then Yield i (s, i+1) else Skip (s, i+1)
820 Skip s -> Skip (s, i+1)
823{-# INLINE toListRev #-}
824toListRev :: Monad m => Stream m a -> m [a]
825toListRev = foldl' (flip (:)) []
827-- We can implement reverse as:
829-- > reverse = foldlS (flip cons) nil
831-- However, this implementation is unusable because of the horrible performance
832-- of cons. So we just convert it to a list first and then stream from the
835-- XXX Maybe we can use an Array instead of a list here?
836{-# INLINE_NORMAL reverse #-}
837reverse :: Monad m => Stream m a -> Stream m a
838reverse m = Stream step Nothing
840 {-# INLINE_LATE step #-}
843 return $ Skip (Just xs)
844 step _ (Just (x:xs)) = return $ Yield x (Just xs)
845 step _ (Just []) = return Stop
847-- Much faster reverse for Storables
848{-# INLINE_NORMAL reverse' #-}
849reverse' :: forall m a. (MonadIO m, Storable a) => Stream m a -> Stream m a
851-- This commented implementation copies the whole stream into one single array
852-- and then streams from that array, this is 3-4x faster than the chunked code
853-- that follows. Though this could be problematic due to unbounded large
854-- allocations. We need to figure out why the chunked code is slower and if we
855-- can optimize the chunked code to work as fast as this one. It may be a
857import Foreign.ForeignPtr (touchForeignPtr)
858import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
859import Foreign.Ptr (Ptr, plusPtr)
860reverse' m = Stream step Nothing
862 {-# INLINE_LATE step #-}
864 arr <- A.fromStreamD m
865 let p = aEnd arr `plusPtr` negate (sizeOf (undefined :: a))
866 return $ Skip $ Just (aStart arr, p)
868 step _ (Just (start, p)) | p < unsafeForeignPtrToPtr start = return Stop
870 step _ (Just (start, p)) = do
871 let !x = A.unsafeInlineIO $ do
873 touchForeignPtr start
875 next = p `plusPtr` negate (sizeOf (undefined :: a))
876 return $ Yield x (Just (start, next))
883 $ A.fromStreamDArraysOf A.defaultChunkSize m
886------------------------------------------------------------------------------
888------------------------------------------------------------------------------
890{-# INLINE_NORMAL splitSuffixBy' #-}
891splitSuffixBy' :: Monad m
892 => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
893splitSuffixBy' predicate f (Stream step state) =
894 Stream (stepOuter f) (Just state)
898 {-# INLINE_LATE stepOuter #-}
899 stepOuter (Fold fstep initial done) gst (Just st) = do
900 res <- step (adaptState gst) st
906 then done acc' >>= \val -> return $ Yield val (Just s)
909 Skip s -> return $ Skip $ Just s
915 res <- step (adaptState gst) stt
920 then done acc' >>= \val -> return $ Yield val (Just s)
922 Skip s -> go SPEC s acc
923 Stop -> done acc >>= \val -> return $ Yield val Nothing
925 stepOuter _ _ Nothing = return Stop
927{-# INLINE_NORMAL groupsBy #-}
933groupsBy cmp f (Stream step state) = Stream (stepOuter f) (Just state, Nothing)
937 {-# INLINE_LATE stepOuter #-}
938 stepOuter (Fold fstep initial done) gst (Just st, Nothing) = do
939 res <- step (adaptState gst) st
946 Skip s -> return $ Skip $ (Just s, Nothing)
951 go !_ prev stt !acc = do
952 res <- step (adaptState gst) stt
959 else done acc >>= \r -> return $ Yield r (Just s, Just x)
960 Skip s -> go SPEC prev s acc
961 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
963 stepOuter (Fold fstep initial done) gst (Just st, Just prev) = do
965 acc' <- fstep acc prev
970 -- XXX code duplicated from the previous equation
972 res <- step (adaptState gst) stt
979 else done acc >>= \r -> return $ Yield r (Just s, Just x)
980 Skip s -> go SPEC s acc
981 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
983 stepOuter _ _ (Nothing,_) = return Stop
985{-# INLINE_NORMAL groupsRollingBy #-}
986groupsRollingBy :: Monad m
991groupsRollingBy cmp f (Stream step state) =
992 Stream (stepOuter f) (Just state, Nothing)
995 {-# INLINE_LATE stepOuter #-}
996 stepOuter (Fold fstep initial done) gst (Just st, Nothing) = do
997 res <- step (adaptState gst) st
1004 Skip s -> return $ Skip $ (Just s, Nothing)
1008 go !_ prev stt !acc = do
1009 res <- step (adaptState gst) stt
1017 done acc >>= \r -> return $ Yield r (Just s, Just x)
1018 Skip s -> go SPEC prev s acc
1019 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1021 stepOuter (Fold fstep initial done) gst (Just st, Just prev') = do
1023 acc' <- fstep acc prev'
1024 go SPEC prev' st acc'
1027 go !_ prevv stt !acc = do
1028 res <- step (adaptState gst) stt
1035 else done acc >>= \r -> return $ Yield r (Just s, Just x)
1036 Skip s -> go SPEC prevv s acc
1037 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1039 stepOuter _ _ (Nothing, _) = return Stop
1041{-# INLINE_NORMAL splitBy #-}
1042splitBy :: Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1043splitBy predicate f (Stream step state) = Stream (step' f) (Just state)
1047 {-# INLINE_LATE step' #-}
1048 step' (Fold fstep initial done) gst (Just st) = initial >>= go SPEC st
1053 res <- step (adaptState gst) stt
1057 then done acc >>= \r -> return $ Yield r (Just s)
1061 Skip s -> go SPEC s acc
1062 Stop -> done acc >>= \r -> return $ Yield r Nothing
1064 step' _ _ Nothing = return Stop
1066{-# INLINE_NORMAL splitSuffixBy #-}
1067splitSuffixBy :: Monad m
1068 => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1069splitSuffixBy predicate f (Stream step state) = Stream (step' f) (Just state)
1073 {-# INLINE_LATE step' #-}
1074 step' (Fold fstep initial done) gst (Just st) = do
1075 res <- step (adaptState gst) st
1080 then done acc >>= \val -> return $ Yield val (Just s)
1085 Skip s -> return $ Skip $ Just s
1091 res <- step (adaptState gst) stt
1095 then done acc >>= \r -> return $ Yield r (Just s)
1099 Skip s -> go SPEC s acc
1100 Stop -> done acc >>= \r -> return $ Yield r Nothing
1102 step' _ _ Nothing = return Stop
1104{-# INLINE_NORMAL wordsBy #-}
1105wordsBy :: Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1106wordsBy predicate f (Stream step state) = Stream (stepOuter f) (Just state)
1110 {-# INLINE_LATE stepOuter #-}
1111 stepOuter (Fold fstep initial done) gst (Just st) = do
1112 res <- step (adaptState gst) st
1116 then return $ Skip (Just s)
1122 Skip s -> return $ Skip $ Just s
1128 res <- step (adaptState gst) stt
1132 then done acc >>= \r -> return $ Yield r (Just s)
1136 Skip s -> go SPEC s acc
1137 Stop -> done acc >>= \r -> return $ Yield r Nothing
1139 stepOuter _ _ Nothing = return Stop
1141-- String search algorithms:
1142-- http://www-igm.univ-mlv.fr/~lecroq/string/index.html
1145-- TODO can we unify the splitting operations using a splitting configuration
1146-- like in the split package.
1148data SplitStyle = Infix | Suffix | Prefix deriving (Eq, Show)
1150data SplitOptions = SplitOptions
1151 { style :: SplitStyle
1152 , withSep :: Bool -- ^ keep the separators in output
1153 -- , compact :: Bool -- ^ treat multiple consecutive separators as one
1154 -- , trimHead :: Bool -- ^ drop blank at head
1155 -- , trimTail :: Bool -- ^ drop blank at tail
1159data SplitOnState s a =
1164 | GO_KARP_RABIN s !(RB.Ring a) !(Ptr a)
1167{-# INLINE_NORMAL splitOn #-}
1169 :: forall m a b. (MonadIO m, Storable a, Enum a, Eq a)
1174splitOn patArr@Array{..} (Fold fstep initial done) (Stream step state) =
1175 Stream stepOuter GO_START
1179 patLen = A.length patArr
1180 maxIndex = patLen - 1
1181 elemBits = sizeOf (undefined :: a) * 8
1183 {-# INLINE_LATE stepOuter #-}
1184 stepOuter _ GO_START =
1186 then return $ Skip $ GO_EMPTY_PAT state
1189 r <- liftIO $ (A.unsafeIndexIO patArr 0)
1190 return $ Skip $ GO_SINGLE_PAT state r
1191 else if sizeOf (undefined :: a) * patLen
1192 <= sizeOf (undefined :: Word)
1193 then return $ Skip $ GO_SHORT_PAT state
1195 (rb, rhead) <- liftIO $ RB.new patLen
1196 return $ Skip $ GO_KARP_RABIN state rb rhead
1198 stepOuter gst (GO_SINGLE_PAT stt pat) = initial >>= go SPEC stt
1203 res <- step (adaptState gst) st
1209 return $ Yield r (GO_SINGLE_PAT s pat)
1210 else fstep acc x >>= go SPEC s
1211 Skip s -> go SPEC s acc
1212 Stop -> done acc >>= \r -> return $ Yield r GO_DONE
1214 stepOuter gst (GO_SHORT_PAT stt) = initial >>= go0 SPEC 0 (0 :: Word) stt
1219 mask = (1 `shiftL` (elemBits * patLen)) - 1
1221 addToWord wrd a = (wrd `shiftL` elemBits) .|. fromIntegral (fromEnum a)
1224 patWord = mask .&. A.foldl' addToWord 0 patArr
1226 go0 !_ !idx wrd st !acc = do
1227 res <- step (adaptState gst) st
1230 let wrd' = addToWord wrd x
1233 if wrd' .&. mask == patWord
1236 return $ Yield r (GO_SHORT_PAT s)
1237 else go1 SPEC wrd' s acc
1238 else go0 SPEC (idx + 1) wrd' s acc
1239 Skip s -> go0 SPEC idx wrd s acc
1242 then go2 wrd idx acc
1244 done acc' >>= \r -> return $ Yield r GO_DONE
1247 go1 !_ wrd st !acc = do
1248 res <- step (adaptState gst) st
1251 let wrd' = addToWord wrd x
1252 old = (mask .&. wrd) `shiftR` (elemBits * (patLen - 1))
1253 acc' <- fstep acc (toEnum $ fromIntegral old)
1254 if wrd' .&. mask == patWord
1255 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1256 else go1 SPEC wrd' s acc'
1257 Skip s -> go1 SPEC wrd s acc
1259 acc' <- go2 wrd patLen acc
1260 done acc' >>= \r -> return $ Yield r GO_DONE
1262 go2 !wrd !n !acc | n > 0 = do
1263 let old = (mask .&. wrd) `shiftR` (elemBits * (n - 1))
1264 fstep acc (toEnum $ fromIntegral old) >>= go2 wrd (n - 1)
1265 go2 _ _ acc = return acc
1267 stepOuter gst (GO_KARP_RABIN stt rb rhead) = do
1268 initial >>= go0 SPEC 0 rhead stt
1272 k = 2891336453 :: Word32
1274 addCksum cksum a = cksum * k + fromIntegral (fromEnum a)
1275 deltaCksum cksum old new =
1276 addCksum cksum new - coeff * fromIntegral (fromEnum old)
1278 -- XXX shall we use a random starting hash or 1 instead of 0?
1279 patHash = A.foldl' addCksum 0 patArr
1282 go0 !_ !idx !rh st !acc = do
1283 res <- step (adaptState gst) st
1286 rh' <- liftIO $ RB.unsafeInsert rb rh x
1289 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1290 let !ringHash = fold addCksum 0 rb
1291 if ringHash == patHash
1292 then go2 SPEC ringHash rh' s acc
1293 else go1 SPEC ringHash rh' s acc
1294 else go0 SPEC (idx + 1) rh' s acc
1295 Skip s -> go0 SPEC idx rh s acc
1297 !acc' <- if idx /= 0
1298 then RB.unsafeFoldRingM rh fstep acc rb
1300 done acc' >>= \r -> return $ Yield r GO_DONE
1302 -- XXX Theoretically this code can do 4 times faster if GHC generates
1303 -- optimal code. If we use just "(cksum' == patHash)" condition it goes
1304 -- 4x faster, as soon as we add the "RB.unsafeEqArray rb v" condition
1305 -- the generated code changes drastically and becomes 4x slower. Need
1306 -- to investigate what is going on with GHC.
1308 go1 !_ !cksum !rh st !acc = do
1309 res <- step (adaptState gst) st
1312 old <- liftIO $ peek rh
1313 let cksum' = deltaCksum cksum old x
1314 acc' <- fstep acc old
1316 if (cksum' == patHash)
1318 rh' <- liftIO (RB.unsafeInsert rb rh x)
1319 go2 SPEC cksum' rh' s acc'
1321 rh' <- liftIO (RB.unsafeInsert rb rh x)
1322 go1 SPEC cksum' rh' s acc'
1323 Skip s -> go1 SPEC cksum rh s acc
1325 acc' <- RB.unsafeFoldRingFullM rh fstep acc rb
1326 done acc' >>= \r -> return $ Yield r GO_DONE
1328 go2 !_ !cksum' !rh' s !acc' = do
1329 if RB.unsafeEqArray rb rh' patArr
1332 return $ Yield r (GO_KARP_RABIN s rb rhead)
1333 else go1 SPEC cksum' rh' s acc'
1335 stepOuter gst (GO_EMPTY_PAT st) = do
1336 res <- step (adaptState gst) st
1341 done acc' >>= \r -> return $ Yield r (GO_EMPTY_PAT s)
1342 Skip s -> return $ Skip (GO_EMPTY_PAT s)
1345 stepOuter _ GO_DONE = return Stop
1347{-# INLINE_NORMAL splitSuffixOn #-}
1349 :: forall m a b. (MonadIO m, Storable a, Enum a, Eq a)
1355splitSuffixOn withSep patArr@Array{..} (Fold fstep initial done)
1356 (Stream step state) =
1357 Stream stepOuter GO_START
1361 patLen = A.length patArr
1362 maxIndex = patLen - 1
1363 elemBits = sizeOf (undefined :: a) * 8
1365 {-# INLINE_LATE stepOuter #-}
1366 stepOuter _ GO_START =
1368 then return $ Skip $ GO_EMPTY_PAT state
1371 r <- liftIO $ (A.unsafeIndexIO patArr 0)
1372 return $ Skip $ GO_SINGLE_PAT state r
1373 else if sizeOf (undefined :: a) * patLen
1374 <= sizeOf (undefined :: Word)
1375 then return $ Skip $ GO_SHORT_PAT state
1377 (rb, rhead) <- liftIO $ RB.new patLen
1378 return $ Skip $ GO_KARP_RABIN state rb rhead
1380 stepOuter gst (GO_SINGLE_PAT stt pat) = do
1381 -- This first part is the only difference between splitOn and
1383 -- If the last element is a separator do not issue a blank segment.
1384 res <- step (adaptState gst) stt
1390 acc' <- if withSep then fstep acc x else return acc
1391 done acc' >>= \r -> return $ Yield r (GO_SINGLE_PAT s pat)
1392 else fstep acc x >>= go SPEC s
1393 Skip s -> return $ Skip $ (GO_SINGLE_PAT s pat)
1398 -- This is identical for splitOn and splitSuffixOn
1400 res <- step (adaptState gst) st
1405 acc' <- if withSep then fstep acc x else return acc
1407 return $ Yield r (GO_SINGLE_PAT s pat)
1408 else fstep acc x >>= go SPEC s
1409 Skip s -> go SPEC s acc
1410 Stop -> done acc >>= \r -> return $ Yield r GO_DONE
1412 stepOuter gst (GO_SHORT_PAT stt) = do
1414 -- Call "initial" only if the stream yields an element, otherwise we
1415 -- may call "initial" but never yield anything. initial may produce a
1416 -- side effect, therefore we will end up doing and discard a side
1421 res <- step (adaptState gst) stt
1425 let wrd' = addToWord wrd x
1426 acc' <- if withSep then fstep acc x else return acc
1429 if wrd' .&. mask == patWord
1430 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1431 else go0 SPEC (idx + 1) wrd' s acc'
1432 else go0 SPEC (idx + 1) wrd' s acc'
1433 Skip s -> return $ Skip (GO_SHORT_PAT s)
1439 mask = (1 `shiftL` (elemBits * patLen)) - 1
1441 addToWord wrd a = (wrd `shiftL` elemBits) .|. fromIntegral (fromEnum a)
1444 patWord = mask .&. A.foldl' addToWord 0 patArr
1446 go0 !_ !idx wrd st !acc = do
1447 res <- step (adaptState gst) st
1450 let wrd' = addToWord wrd x
1451 acc' <- if withSep then fstep acc x else return acc
1454 if wrd' .&. mask == patWord
1457 return $ Yield r (GO_SHORT_PAT s)
1458 else go1 SPEC wrd' s acc'
1459 else go0 SPEC (idx + 1) wrd' s acc'
1460 Skip s -> go0 SPEC idx wrd s acc
1462 if (idx == maxIndex) && (wrd .&. mask == patWord)
1465 acc' <- if idx /= 0 && not withSep
1466 then go2 wrd idx acc
1468 done acc' >>= \r -> return $ Yield r GO_DONE
1471 go1 !_ wrd st !acc = do
1472 res <- step (adaptState gst) st
1475 let wrd' = addToWord wrd x
1476 old = (mask .&. wrd) `shiftR` (elemBits * (patLen - 1))
1479 else fstep acc (toEnum $ fromIntegral old)
1480 if wrd' .&. mask == patWord
1481 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1482 else go1 SPEC wrd' s acc'
1483 Skip s -> go1 SPEC wrd s acc
1485 -- If the last sequence is a separator do not issue a blank
1487 if wrd .&. mask == patWord
1492 else go2 wrd patLen acc
1493 done acc' >>= \r -> return $ Yield r GO_DONE
1495 go2 !wrd !n !acc | n > 0 = do
1496 let old = (mask .&. wrd) `shiftR` (elemBits * (n - 1))
1497 fstep acc (toEnum $ fromIntegral old) >>= go2 wrd (n - 1)
1498 go2 _ _ acc = return acc
1500 stepOuter gst (GO_KARP_RABIN stt rb rhead) = do
1502 res <- step (adaptState gst) stt
1506 acc' <- if withSep then fstep acc x else return acc
1507 rh' <- liftIO (RB.unsafeInsert rb rhead x)
1510 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1511 let !ringHash = fold addCksum 0 rb
1512 if ringHash == patHash
1513 then go2 SPEC ringHash rh' s acc'
1514 else go0 SPEC (idx + 1) rh' s acc'
1515 else go0 SPEC (idx + 1) rh' s acc'
1516 Skip s -> return $ Skip (GO_KARP_RABIN s rb rhead)
1521 k = 2891336453 :: Word32
1523 addCksum cksum a = cksum * k + fromIntegral (fromEnum a)
1524 deltaCksum cksum old new =
1525 addCksum cksum new - coeff * fromIntegral (fromEnum old)
1527 -- XXX shall we use a random starting hash or 1 instead of 0?
1528 patHash = A.foldl' addCksum 0 patArr
1531 go0 !_ !idx !rh st !acc = do
1532 res <- step (adaptState gst) st
1535 acc' <- if withSep then fstep acc x else return acc
1536 rh' <- liftIO (RB.unsafeInsert rb rh x)
1539 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1540 let !ringHash = fold addCksum 0 rb
1541 if ringHash == patHash
1542 then go2 SPEC ringHash rh' s acc'
1543 else go1 SPEC ringHash rh' s acc'
1544 else go0 SPEC (idx + 1) rh' s acc'
1545 Skip s -> go0 SPEC idx rh s acc
1547 -- do not issue a blank segment when we end at pattern
1548 if (idx == maxIndex) && RB.unsafeEqArray rb rh patArr
1551 !acc' <- if idx /= 0 && not withSep
1552 then RB.unsafeFoldRingM rh fstep acc rb
1554 done acc' >>= \r -> return $ Yield r GO_DONE
1556 -- XXX Theoretically this code can do 4 times faster if GHC generates
1557 -- optimal code. If we use just "(cksum' == patHash)" condition it goes
1558 -- 4x faster, as soon as we add the "RB.unsafeEqArray rb v" condition
1559 -- the generated code changes drastically and becomes 4x slower. Need
1560 -- to investigate what is going on with GHC.
1562 go1 !_ !cksum !rh st !acc = do
1563 res <- step (adaptState gst) st
1566 old <- liftIO $ peek rh
1567 let cksum' = deltaCksum cksum old x
1572 if (cksum' == patHash)
1574 rh' <- liftIO (RB.unsafeInsert rb rh x)
1575 go2 SPEC cksum' rh' s acc'
1577 rh' <- liftIO (RB.unsafeInsert rb rh x)
1578 go1 SPEC cksum' rh' s acc'
1579 Skip s -> go1 SPEC cksum rh s acc
1581 if RB.unsafeEqArray rb rh patArr
1586 else RB.unsafeFoldRingFullM rh fstep acc rb
1587 done acc' >>= \r -> return $ Yield r GO_DONE
1589 go2 !_ !cksum' !rh' s !acc' = do
1590 if RB.unsafeEqArray rb rh' patArr
1593 return $ Yield r (GO_KARP_RABIN s rb rhead)
1594 else go1 SPEC cksum' rh' s acc'
1596 stepOuter gst (GO_EMPTY_PAT st) = do
1597 res <- step (adaptState gst) st
1602 done acc' >>= \r -> return $ Yield r (GO_EMPTY_PAT s)
1603 Skip s -> return $ Skip (GO_EMPTY_PAT s)
1606 stepOuter _ GO_DONE = return Stop
1608------------------------------------------------------------------------------
1610------------------------------------------------------------------------------
1612{-# INLINE_NORMAL isPrefixOf #-}
1613isPrefixOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
1614isPrefixOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
1616 go (sa, sb, Nothing) = do
1617 r <- stepa defState sa
1619 Yield x sa' -> go (sa', sb, Just x)
1620 Skip sa' -> go (sa', sb, Nothing)
1623 go (sa, sb, Just x) = do
1624 r <- stepb defState sb
1628 then go (sa, sb', Nothing)
1630 Skip sb' -> go (sa, sb', Just x)
1631 Stop -> return False
1633{-# INLINE_NORMAL isSubsequenceOf #-}
1634isSubsequenceOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
1635isSubsequenceOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
1637 go (sa, sb, Nothing) = do
1638 r <- stepa defState sa
1640 Yield x sa' -> go (sa', sb, Just x)
1641 Skip sa' -> go (sa', sb, Nothing)
1644 go (sa, sb, Just x) = do
1645 r <- stepb defState sb
1649 then go (sa, sb', Nothing)
1650 else go (sa, sb', Just x)
1651 Skip sb' -> go (sa, sb', Just x)
1652 Stop -> return False
1654{-# INLINE_NORMAL stripPrefix #-}
1657 => Stream m a -> Stream m a -> m (Maybe (Stream m a))
1658stripPrefix (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
1660 go (sa, sb, Nothing) = do
1661 r <- stepa defState sa
1663 Yield x sa' -> go (sa', sb, Just x)
1664 Skip sa' -> go (sa', sb, Nothing)
1665 Stop -> return $ Just (Stream stepb sb)
1667 go (sa, sb, Just x) = do
1668 r <- stepb defState sb
1672 then go (sa, sb', Nothing)
1674 Skip sb' -> go (sa, sb', Just x)
1675 Stop -> return Nothing
1677------------------------------------------------------------------------------
1679------------------------------------------------------------------------------
1681-- | Execute a monadic action for each element of the 'Stream'
1682{-# INLINE_NORMAL mapM_ #-}
1683mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
1684mapM_ m = drain . mapM m
1686------------------------------------------------------------------------------
1688------------------------------------------------------------------------------
1690-- | Run a side effect before the stream yields its first element.
1691{-# INLINE_NORMAL before #-}
1692before :: Monad m => m b -> Stream m a -> Stream m a
1693before action (Stream step state) = Stream step' Nothing
1697 {-# INLINE_LATE step' #-}
1698 step' _ Nothing = action >> return (Skip (Just state))
1700 step' gst (Just st) = do
1703 Yield x s -> return $ Yield x (Just s)
1704 Skip s -> return $ Skip (Just s)
1707-- | Run a side effect whenever the stream stops normally.
1708{-# INLINE_NORMAL after #-}
1709after :: Monad m => m b -> Stream m a -> Stream m a
1710after action (Stream step state) = Stream step' state
1714 {-# INLINE_LATE step' #-}
1718 Yield x s -> return $ Yield x s
1719 Skip s -> return $ Skip s
1720 Stop -> action >> return Stop
1722-- XXX These combinators are expensive due to the call to
1723-- onException/handle/try on each step. Therefore, when possible, they should
1724-- be called in an outer loop where we perform less iterations. For example, we
1725-- cannot call them on each iteration in a char stream, instead we can call
1726-- them when doing an IO on an array.
1728-- XXX For high performance error checks in busy streams we may need another
1729-- Error constructor in step.
1731-- | Run a side effect whenever the stream aborts due to an exception. The
1732-- exception is not caught simply rethrown.
1733{-# INLINE_NORMAL onException #-}
1734onException :: MonadCatch m => m b -> Stream m a -> Stream m a
1735onException action (Stream step state) = Stream step' state
1739 {-# INLINE_LATE step' #-}
1741 res <- step gst st `MC.onException` action
1743 Yield x s -> return $ Yield x s
1744 Skip s -> return $ Skip s
1747-- | Run a side effect whenever the stream stops normally or aborts due to an
1749{-# INLINE finally #-}
1750finally :: MonadCatch m => m b -> Stream m a -> Stream m a
1751finally action xs = after action $ onException action xs
1753-- XXX bracket is like concatMap, it generates a stream and then flattens it.
1754-- Like concatMap it has 10x worse performance compared to linear fused
1757-- | Run the first action before the stream starts and remember its output,
1758-- generate a stream using the output, run the second action using the
1759-- remembered value as an argument whenever the stream ends normally or due to
1761{-# INLINE_NORMAL bracket #-}
1762bracket :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
1763bracket bef aft bet = Stream step' Nothing
1767 {-# INLINE_LATE step' #-}
1768 step' _ Nothing = bef >>= \x -> return (Skip (Just (bet x, x)))
1770 -- NOTE: It is important to use UnStream instead of the Stream pattern
1771 -- here, otherwise we get huge perf degradation, see note in concatMap.
1772 step' gst (Just (UnStream step state, v)) = do
1773 res <- step gst state `MC.onException` aft v
1775 Yield x s -> return $ Yield x (Just (Stream step s, v))
1776 Skip s -> return $ Skip (Just (Stream step s, v))
1777 Stop -> aft v >> return Stop
1779-- | When evaluating a stream if an exception occurs, stream evaluation aborts
1780-- and the specified exception handler is run with the exception as argument.
1781{-# INLINE_NORMAL handle #-}
1782handle :: (MonadCatch m, Exception e) => (e -> m a) -> Stream m a -> Stream m a
1783handle f (Stream step state) = Stream step' (Just state)
1787 {-# INLINE_LATE step' #-}
1788 step' gst (Just st) = do
1789 res <- MC.try $ step gst st
1791 Left e -> f e >>= \x -> return (Yield x Nothing)
1792 Right r -> case r of
1793 Yield x s -> return $ Yield x (Just s)
1794 Skip s -> return $ Skip (Just s)
1797 step' _ Nothing = return Stop
1799-------------------------------------------------------------------------------
1800-- General transformation
1801-------------------------------------------------------------------------------
1803{-# INLINE_NORMAL transform #-}
1804transform :: Monad m => Pipe m a b -> Stream m a -> Stream m b
1805transform (Pipe pstep1 pstep2 pstate) (Stream step state) =
1806 Stream step' (Consume pstate, state)
1810 {-# INLINE_LATE step' #-}
1812 step' gst (Consume pst, st) = pst `seq` do
1813 r <- step (adaptState gst) st
1818 Pipe.Yield b pst' -> return $ Yield b (pst', s)
1819 Pipe.Continue pst' -> return $ Skip (pst', s)
1820 Skip s -> return $ Skip (Consume pst, s)
1823 step' _ (Produce pst, st) = pst `seq` do
1826 Pipe.Yield b pst' -> return $ Yield b (pst', st)
1827 Pipe.Continue pst' -> return $ Skip (pst', st)
1829------------------------------------------------------------------------------
1830-- Transformation by Folding (Scans)
1831------------------------------------------------------------------------------
1833------------------------------------------------------------------------------
1835------------------------------------------------------------------------------
1837-- XXX Is a prescan useful, discarding the last step does not sound useful? I
1838-- am not sure about the utility of this function, so this is implemented but
1839-- not exposed. We can expose it if someone provides good reasons why this is
1842-- XXX We have to execute the stream one step ahead to know that we are at the
1843-- last step. The vector implementation of prescan executes the last fold step
1844-- but does not yield the result. This means we have executed the effect but
1845-- discarded value. This does not sound right. In this implementation we are
1846-- not executing the last fold step.
1847{-# INLINE_NORMAL prescanlM' #-}
1848prescanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
1849prescanlM' f mz (Stream step state) = Stream step' (state, mz)
1851 {-# INLINE_LATE step' #-}
1852 step' gst (st, prev) = do
1853 r <- step (adaptState gst) st
1857 return $ Yield acc (s, f acc x)
1858 Skip s -> return $ Skip (s, prev)
1861{-# INLINE prescanl' #-}
1862prescanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
1863prescanl' f z = prescanlM' (\a b -> return (f a b)) (return z)
1865------------------------------------------------------------------------------
1866-- Monolithic postscans (postscan followed by a map)
1867------------------------------------------------------------------------------
1869-- The performance of a modular postscan followed by a map seems to be
1870-- equivalent to this monolithic scan followed by map therefore we may not need
1871-- this implementation. We just have it for performance comparison and in case
1872-- modular version does not perform well in some situation.
1874{-# INLINE_NORMAL postscanlMx' #-}
1875postscanlMx' :: Monad m
1876 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
1877postscanlMx' fstep begin done (Stream step state) = do
1878 Stream step' (state, begin)
1880 {-# INLINE_LATE step' #-}
1881 step' gst (st, acc) = do
1882 r <- step (adaptState gst) st
1888 v `seq` y `seq` return (Yield v (s, return y))
1889 Skip s -> return $ Skip (s, acc)
1892{-# INLINE_NORMAL postscanlx' #-}
1893postscanlx' :: Monad m
1894 => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
1895postscanlx' fstep begin done s =
1896 postscanlMx' (\b a -> return (fstep b a)) (return begin) (return . done) s
1898-- XXX do we need consM strict to evaluate the begin value?
1899{-# INLINE scanlMx' #-}
1901 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
1902scanlMx' fstep begin done s =
1903 (begin >>= \x -> x `seq` done x) `consM` postscanlMx' fstep begin done s
1905{-# INLINE scanlx' #-}
1907 => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
1908scanlx' fstep begin done s =
1909 scanlMx' (\b a -> return (fstep b a)) (return begin) (return . done) s
1911------------------------------------------------------------------------------
1913------------------------------------------------------------------------------
1915-- XXX if we make the initial value of the accumulator monadic then should we
1916-- execute it even if the stream is empty? In that case we would have generated
1917-- the effect but discarded the value, but that is what a fold does when the
1918-- stream is empty. Whatever we decide, need to reconcile this with prescan.
1919-- If we execute the initial value here without even using it then it is ok to
1920-- execute the last step there as well without using the value.
1921-- Looking at the duality with right fold, in case of right fold we always
1922-- perform the action when the construction terminates, so in case of left fold
1923-- we should perform it only when the reduction starts.
1924{-# INLINE_NORMAL postscanlM' #-}
1925postscanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
1926postscanlM' fstep begin (Stream step state) =
1927 begin `seq` Stream step' (state, begin)
1929 {-# INLINE_LATE step' #-}
1930 step' gst (st, acc) = acc `seq` do
1931 r <- step (adaptState gst) st
1935 y `seq` return (Yield y (s, y))
1936 Skip s -> return $ Skip (s, acc)
1939{-# INLINE_NORMAL postscanl' #-}
1940postscanl' :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
1941postscanl' f = postscanlM' (\a b -> return (f a b))
1943{-# INLINE_NORMAL postscanlM #-}
1944postscanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
1945postscanlM fstep begin (Stream step state) = Stream step' (state, begin)
1947 {-# INLINE_LATE step' #-}
1948 step' gst (st, acc) = do
1949 r <- step (adaptState gst) st
1953 return (Yield y (s, y))
1954 Skip s -> return $ Skip (s, acc)
1957{-# INLINE_NORMAL postscanl #-}
1958postscanl :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
1959postscanl f = postscanlM (\a b -> return (f a b))
1961{-# INLINE_NORMAL scanlM' #-}
1962scanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
1963scanlM' fstep begin s = begin `seq` (begin `cons` postscanlM' fstep begin s)
1965{-# INLINE scanl' #-}
1966scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
1967scanl' f = scanlM' (\a b -> return (f a b))
1969{-# INLINE_NORMAL scanlM #-}
1970scanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
1971scanlM fstep begin s = begin `cons` postscanlM fstep begin s
1974scanl :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
1975scanl f = scanlM (\a b -> return (f a b))
1977{-# INLINE_NORMAL scanl1M #-}
1978scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
1979scanl1M fstep (Stream step state) = Stream step' (state, Nothing)
1981 {-# INLINE_LATE step' #-}
1982 step' gst (st, Nothing) = do
1985 Yield x s -> return $ Yield x (s, Just x)
1986 Skip s -> return $ Skip (s, Nothing)
1989 step' gst (st, Just acc) = do
1994 return $ Yield z (s, Just z)
1995 Skip s -> return $ Skip (s, Just acc)
1998{-# INLINE scanl1 #-}
1999scanl1 :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
2000scanl1 f = scanl1M (\x y -> return (f x y))
2002{-# INLINE_NORMAL scanl1M' #-}
2003scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
2004scanl1M' fstep (Stream step state) = Stream step' (state, Nothing)
2006 {-# INLINE_LATE step' #-}
2007 step' gst (st, Nothing) = do
2010 Yield x s -> x `seq` return $ Yield x (s, Just x)
2011 Skip s -> return $ Skip (s, Nothing)
2014 step' gst (st, Just acc) = acc `seq` do
2019 z `seq` return $ Yield z (s, Just z)
2020 Skip s -> return $ Skip (s, Just acc)
2023{-# INLINE scanl1' #-}
2024scanl1' :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
2025scanl1' f = scanl1M' (\x y -> return (f x y))
2028tap :: Monad m => Sink m a -> Stream m a -> Stream m a
2029tap (Sink fstep) (Stream step state) = Stream step' state
2039 Skip s -> return $ Skip s
2040 Stop -> return $ Stop
2042-------------------------------------------------------------------------------
2044-------------------------------------------------------------------------------
2046{-# INLINE_NORMAL takeWhileM #-}
2047takeWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
2048takeWhileM f (Stream step state) = Stream step' state
2050 {-# INLINE_LATE step' #-}
2056 return $ if b then Yield x s else Stop
2057 Skip s -> return $ Skip s
2060{-# INLINE takeWhile #-}
2061takeWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
2062takeWhile f = takeWhileM (return . f)
2064{-# INLINE_NORMAL drop #-}
2065drop :: Monad m => Int -> Stream m a -> Stream m a
2066drop n (Stream step state) = Stream step' (state, Just n)
2068 {-# INLINE_LATE step' #-}
2069 step' gst (st, Just i)
2074 Yield _ s -> Skip (s, Just (i - 1))
2075 Skip s -> Skip (s, Just i)
2077 | otherwise = return $ Skip (st, Nothing)
2079 step' gst (st, Nothing) = do
2083 Yield x s -> Yield x (s, Nothing)
2084 Skip s -> Skip (s, Nothing)
2087data DropWhileState s a
2089 | DropWhileYield a s
2092{-# INLINE_NORMAL dropWhileM #-}
2093dropWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
2094dropWhileM f (Stream step state) = Stream step' (DropWhileDrop state)
2096 {-# INLINE_LATE step' #-}
2097 step' gst (DropWhileDrop st) = do
2103 then return $ Skip (DropWhileDrop s)
2104 else return $ Skip (DropWhileYield x s)
2105 Skip s -> return $ Skip (DropWhileDrop s)
2108 step' gst (DropWhileNext st) = do
2111 Yield x s -> return $ Skip (DropWhileYield x s)
2112 Skip s -> return $ Skip (DropWhileNext s)
2115 step' _ (DropWhileYield x st) = return $ Yield x (DropWhileNext st)
2117{-# INLINE dropWhile #-}
2118dropWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
2119dropWhile f = dropWhileM (return . f)
2121{-# INLINE_NORMAL filterM #-}
2122filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
2123filterM f (Stream step state) = Stream step' state
2125 {-# INLINE_LATE step' #-}
2134 Skip s -> return $ Skip s
2137{-# INLINE filter #-}
2138filter :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
2139filter f = filterM (return . f)
2141{-# INLINE_NORMAL uniq #-}
2142uniq :: (Eq a, Monad m) => Stream m a -> Stream m a
2143uniq (Stream step state) = Stream step' (Nothing, state)
2145 {-# INLINE_LATE step' #-}
2146 step' gst (Nothing, st) = do
2149 Yield x s -> return $ Yield x (Just x, s)
2150 Skip s -> return $ Skip (Nothing, s)
2152 step' gst (Just x, st) = do
2155 Yield y s | x == y -> return $ Skip (Just x, s)
2156 | otherwise -> return $ Yield y (Just y, s)
2157 Skip s -> return $ Skip (Just x, s)
2160------------------------------------------------------------------------------
2161-- Transformation by Mapping
2162------------------------------------------------------------------------------
2164{-# INLINE_NORMAL sequence #-}
2165sequence :: Monad m => Stream m (m a) -> Stream m a
2166sequence (Stream step state) = Stream step' state
2168 {-# INLINE_LATE step' #-}
2170 r <- step (adaptState gst) st
2172 Yield x s -> x >>= \a -> return (Yield a s)
2173 Skip s -> return $ Skip s
2176------------------------------------------------------------------------------
2178------------------------------------------------------------------------------
2180data LoopState x s = FirstYield s
2181 | InterspersingYield s
2184{-# INLINE_NORMAL intersperseM #-}
2185intersperseM :: Monad m => m a -> Stream m a -> Stream m a
2186intersperseM m (Stream step state) = Stream step' (FirstYield state)
2188 {-# INLINE_LATE step' #-}
2189 step' gst (FirstYield st) = do
2193 Yield x s -> Skip (YieldAndCarry x s)
2194 Skip s -> Skip (FirstYield s)
2197 step' gst (InterspersingYield st) = do
2202 return $ Yield a (YieldAndCarry x s)
2203 Skip s -> return $ Skip $ InterspersingYield s
2206 step' _ (YieldAndCarry x st) = return $ Yield x (InterspersingYield st)
2211 | SuffixYield a (SuffixState s a)
2213{-# INLINE_NORMAL insertAfterEach #-}
2214insertAfterEach :: forall m a. Monad m => m a -> Stream m a -> Stream m a
2215insertAfterEach action (Stream step state) = Stream step' (SuffixElem state)
2217 {-# INLINE_LATE step' #-}
2218 step' gst (SuffixElem st) = do
2221 Yield x s -> Skip (SuffixYield x (SuffixSuffix s))
2222 Skip s -> Skip (SuffixElem s)
2225 step' _ (SuffixSuffix st) = do
2226 action >>= \r -> return $ Skip (SuffixYield r (SuffixElem st))
2228 step' _ (SuffixYield x next) = return $ Yield x next
2230{-# INLINE intersperse #-}
2231intersperse :: Monad m => a -> Stream m a -> Stream m a
2232intersperse a = intersperseM (return a)
2234{-# INLINE_NORMAL insertBy #-}
2235insertBy :: Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
2236insertBy cmp a (Stream step state) = Stream step' (state, False, Nothing)
2238 {-# INLINE_LATE step' #-}
2239 step' gst (st, False, _) = do
2242 Yield x s -> case cmp a x of
2243 GT -> return $ Yield x (s, False, Nothing)
2244 _ -> return $ Yield a (s, True, Just x)
2245 Skip s -> return $ Skip (s, False, Nothing)
2246 Stop -> return $ Yield a (st, True, Nothing)
2248 step' _ (_, True, Nothing) = return Stop
2250 step' gst (st, True, Just prev) = do
2253 Yield x s -> return $ Yield prev (s, True, Just x)
2254 Skip s -> return $ Skip (s, True, Just prev)
2255 Stop -> return $ Yield prev (st, True, Nothing)
2257------------------------------------------------------------------------------
2259------------------------------------------------------------------------------
2261{-# INLINE_NORMAL deleteBy #-}
2262deleteBy :: Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a
2263deleteBy eq x (Stream step state) = Stream step' (state, False)
2265 {-# INLINE_LATE step' #-}
2266 step' gst (st, False) = do
2269 Yield y s -> return $
2270 if eq x y then Skip (s, True) else Yield y (s, False)
2271 Skip s -> return $ Skip (s, False)
2274 step' gst (st, True) = do
2277 Yield y s -> return $ Yield y (s, True)
2278 Skip s -> return $ Skip (s, True)
2281------------------------------------------------------------------------------
2282-- Transformation by Map and Filter
2283------------------------------------------------------------------------------
2285-- XXX Will this always fuse properly?
2286{-# INLINE_NORMAL mapMaybe #-}
2287mapMaybe :: Monad m => (a -> Maybe b) -> Stream m a -> Stream m b
2288mapMaybe f = fmap fromJust . filter isJust . map f
2290{-# INLINE_NORMAL mapMaybeM #-}
2291mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b
2292mapMaybeM f = fmap fromJust . filter isJust . mapM f
2294------------------------------------------------------------------------------
2296------------------------------------------------------------------------------
2298{-# INLINE_NORMAL indexed #-}
2299indexed :: Monad m => Stream m a -> Stream m (Int, a)
2300indexed (Stream step state) = Stream step' (state, 0)
2302 {-# INLINE_LATE step' #-}
2303 step' gst (st, i) = i `seq` do
2304 r <- step (adaptState gst) st
2306 Yield x s -> return $ Yield (i, x) (s, i+1)
2307 Skip s -> return $ Skip (s, i)
2310{-# INLINE_NORMAL indexedR #-}
2311indexedR :: Monad m => Int -> Stream m a -> Stream m (Int, a)
2312indexedR m (Stream step state) = Stream step' (state, m)
2314 {-# INLINE_LATE step' #-}
2315 step' gst (st, i) = i `seq` do
2316 r <- step (adaptState gst) st
2318 Yield x s -> let i' = i - 1
2319 in return $ Yield (i, x) (s, i')
2320 Skip s -> return $ Skip (s, i)
2323{-# INLINE_NORMAL zipWithM #-}
2325 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
2326zipWithM f (Stream stepa ta) (Stream stepb tb) = Stream step (ta, tb, Nothing)
2328 {-# INLINE_LATE step #-}
2329 step gst (sa, sb, Nothing) = do
2330 r <- stepa (adaptState gst) sa
2333 Yield x sa' -> Skip (sa', sb, Just x)
2334 Skip sa' -> Skip (sa', sb, Nothing)
2337 step gst (sa, sb, Just x) = do
2338 r <- stepb (adaptState gst) sb
2342 return $ Yield z (sa, sb', Nothing)
2343 Skip sb' -> return $ Skip (sa, sb', Just x)
2346{-# RULES "zipWithM xs xs"
2347 forall f xs. zipWithM f xs xs = mapM (\x -> f x x) xs #-}
2349{-# INLINE zipWith #-}
2350zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
2351zipWith f = zipWithM (\a b -> return (f a b))
2353------------------------------------------------------------------------------
2355------------------------------------------------------------------------------
2357{-# INLINE_NORMAL mergeByM #-}
2360 => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
2361mergeByM cmp (Stream stepa ta) (Stream stepb tb) =
2362 Stream step (Just ta, Just tb, Nothing, Nothing)
2364 {-# INLINE_LATE step #-}
2366 -- one of the values is missing, and the corresponding stream is running
2367 step gst (Just sa, sb, Nothing, b) = do
2370 Yield a sa' -> Skip (Just sa', sb, Just a, b)
2371 Skip sa' -> Skip (Just sa', sb, Nothing, b)
2372 Stop -> Skip (Nothing, sb, Nothing, b)
2374 step gst (sa, Just sb, a, Nothing) = do
2377 Yield b sb' -> Skip (sa, Just sb', a, Just b)
2378 Skip sb' -> Skip (sa, Just sb', a, Nothing)
2379 Stop -> Skip (sa, Nothing, a, Nothing)
2381 -- both the values are available
2382 step _ (sa, sb, Just a, Just b) = do
2384 return $ case res of
2385 GT -> Yield b (sa, sb, Just a, Nothing)
2386 _ -> Yield a (sa, sb, Nothing, Just b)
2388 -- one of the values is missing, corresponding stream is done
2389 step _ (Nothing, sb, Nothing, Just b) =
2390 return $ Yield b (Nothing, sb, Nothing, Nothing)
2392 step _ (sa, Nothing, Just a, Nothing) =
2393 return $ Yield a (sa, Nothing, Nothing, Nothing)
2395 step _ (Nothing, Nothing, Nothing, Nothing) = return Stop
2397{-# INLINE mergeBy #-}
2400 => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
2401mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
2403------------------------------------------------------------------------------
2404-- Transformation comprehensions
2405------------------------------------------------------------------------------
2407{-# INLINE_NORMAL the #-}
2408the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
2409the (Stream step state) = go state
2412 r <- step defState st
2414 Yield x s -> go' x s
2416 Stop -> return Nothing
2418 r <- step defState st
2420 Yield x s | x == n -> go' n s
2421 | otherwise -> return Nothing
2423 Stop -> return (Just n)
2425--------------------------------------------------------------------------------
2426-- UTF8 Encoding / Decoding
2427--------------------------------------------------------------------------------
2429-- UTF-8 primitives, Lifted from GHC.IO.Encoding.UTF8.
2431ord2 :: Char -> [Word8]
2432ord2 c = assert (n >= 0x80 && n <= 0x07ff) [x1, x2]
2435 x1 = fromIntegral $ (n `shiftR` 6) + 0xC0
2436 x2 = fromIntegral $ (n .&. 0x3F) + 0x80
2438ord3 :: Char -> [Word8]
2439ord3 c = assert (n >= 0x0800 && n <= 0xffff) [x1, x2, x3]
2442 x1 = fromIntegral $ (n `shiftR` 12) + 0xE0
2443 x2 = fromIntegral $ ((n `shiftR` 6) .&. 0x3F) + 0x80
2444 x3 = fromIntegral $ (n .&. 0x3F) + 0x80
2446ord4 :: Char -> [Word8]
2447ord4 c = assert (n >= 0x10000) [x1, x2, x3, x4]
2450 x1 = fromIntegral $ (n `shiftR` 18) + 0xF0
2451 x2 = fromIntegral $ ((n `shiftR` 12) .&. 0x3F) + 0x80
2452 x3 = fromIntegral $ ((n `shiftR` 6) .&. 0x3F) + 0x80
2453 x4 = fromIntegral $ (n .&. 0x3F) + 0x80
2456chr2 :: Word8 -> Word8 -> Char
2457chr2 (W8# x1#) (W8# x2#) = C# (chr# (z1# +# z2#))
2459 !y1# = word2Int# x1#
2460 !y2# = word2Int# x2#
2461 !z1# = uncheckedIShiftL# (y1# -# 192#) 6#
2465chr3 :: Word8 -> Word8 -> Word8 -> Char
2466chr3 (W8# x1#) (W8# x2#) (W8# x3#) = C# (chr# (z1# +# z2# +# z3#))
2468 !y1# = word2Int# x1#
2469 !y2# = word2Int# x2#
2470 !y3# = word2Int# x3#
2471 !z1# = uncheckedIShiftL# (y1# -# 224#) 12#
2472 !z2# = uncheckedIShiftL# (y2# -# 128#) 6#
2476chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char
2477chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) =
2478 C# (chr# (z1# +# z2# +# z3# +# z4#))
2480 !y1# = word2Int# x1#
2481 !y2# = word2Int# x2#
2482 !y3# = word2Int# x3#
2483 !y4# = word2Int# x4#
2484 !z1# = uncheckedIShiftL# (y1# -# 240#) 18#
2485 !z2# = uncheckedIShiftL# (y2# -# 128#) 12#
2486 !z3# = uncheckedIShiftL# (y3# -# 128#) 6#
2489{-# INLINE between #-}
2491 Word8 -- ^ byte to check
2492 -> Word8 -- ^ lower bound
2493 -> Word8 -- ^ upper bound
2495between x y z = x >= y && x <= z
2497{-# INLINE validate3 #-}
2498validate3 :: Word8 -> Word8 -> Word8 -> Bool
2499validate3 x1 x2 x3 = validate3_1 ||
2504 validate3_1 = (x1 == 0xE0) &&
2505 between x2 0xA0 0xBF &&
2506 between x3 0x80 0xBF
2507 validate3_2 = between x1 0xE1 0xEC &&
2508 between x2 0x80 0xBF &&
2509 between x3 0x80 0xBF
2510 validate3_3 = x1 == 0xED &&
2511 between x2 0x80 0x9F &&
2512 between x3 0x80 0xBF
2513 validate3_4 = between x1 0xEE 0xEF &&
2514 between x2 0x80 0xBF &&
2515 between x3 0x80 0xBF
2517{-# INLINE validate4 #-}
2518validate4 :: Word8 -> Word8 -> Word8 -> Word8 -> Bool
2519validate4 x1 x2 x3 x4 = validate4_1 ||
2523 validate4_1 = x1 == 0xF0 &&
2524 between x2 0x90 0xBF &&
2525 between x3 0x80 0xBF &&
2526 between x4 0x80 0xBF
2527 validate4_2 = between x1 0xF1 0xF3 &&
2528 between x2 0x80 0xBF &&
2529 between x3 0x80 0xBF &&
2530 between x4 0x80 0xBF
2531 validate4_3 = x1 == 0xF4 &&
2532 between x2 0x80 0x8F &&
2533 between x3 0x80 0xBF &&
2534 between x4 0x80 0xBF
2536data CodePoint = FreshPoint
2539 | Three !Word8 !Word8
2541 | Four1 !Word8 !Word8
2542 | Four !Word8 !Word8 !Word8
2545{-# INLINE_NORMAL decodeUtf8 #-}
2546decodeUtf8 :: Monad m => Stream m Word8 -> Stream m Char
2547decodeUtf8 (Stream step state) = Stream step' (state, FreshPoint)
2549 {-# INLINE_LATE step' #-}
2550 step' gst (st, FreshPoint) = do
2551 r <- step (adaptState gst) st
2556 Skip (s, YieldPoint $ unsafeChr (fromIntegral c0))
2557 | c0 >= 0xc0 && c0 <= 0xc1 -> error "Invalid Overlong forms"
2558 | c0 >= 0xc2 && c0 <= 0xdf -> Skip (s, Two c0)
2559 | c0 >= 0xe0 && c0 <= 0xef -> Skip (s, GoThree c0)
2560 | c0 >= 0xf0 -> Skip (s, GoFour c0)
2561 | otherwise -> error "Invalid Sequence"
2562 Skip s -> Skip (s, FreshPoint)
2565 -- Decoding of a UTF8 character that spans two bytes with one byte (c0)
2567 step' gst (st, Two c0) = do
2568 r <- step (adaptState gst) st
2572 | c1 < 0x80 || c1 >= 0xc0 -> error "Invalid Sequence"
2573 | otherwise -> Skip (s, YieldPoint $ chr2 c0 c1)
2574 Skip s -> Skip (s, Two c0)
2575 Stop -> error "Input Underflow"
2577 -- Decoding of a UTF8 character that spans three bytes with first byte (c0)
2579 step' gst (st, GoThree c0) = do
2580 r <- step (adaptState gst) st
2584 | not (validate3 c0 c1 0x80) -> error "Invalid Sequence"
2586 | otherwise -> Skip (s, Three c0 c1)
2587 Skip s -> Skip (s, GoThree c0)
2588 Stop -> error "Input Underflow"
2590 -- Two bytes known of a 3 byte UTF8 encoded unicode character.
2591 step' gst (st, Three c0 c1) = do
2592 r <- step (adaptState gst) st
2596 | not (validate3 c0 c1 c2) -> error "Invalid Sequence"
2597 | otherwise -> Skip (s, YieldPoint $ chr3 c0 c1 c2)
2598 Skip s -> Skip (s, Three c0 c1)
2599 Stop -> error "Input Underflow"
2601 -- One byte known of a four byte UTF8 unicode character.
2602 step' gst (st, GoFour c0) = do
2603 r <- step (adaptState gst) st
2607 | not (validate4 c0 c1 0x80 0x80) -> error "Invalid Sequence"
2608 | otherwise -> Skip (s, Four1 c0 c1)
2609 Skip s -> Skip (s, GoFour c0)
2610 Stop -> error "Input Underflow"
2612 -- Two bytes known of a four byte UTF8 unicode character.
2613 step' gst (st, Four1 c0 c1) = do
2614 r <- step (adaptState gst) st
2618 | not (validate4 c0 c1 c2 0x80) -> error "Invalid Sequence"
2619 | otherwise -> Skip (s, Four c0 c1 c2)
2620 Skip s -> Skip (s, Four1 c0 c1)
2621 Stop -> error "Input Underflow"
2623 -- Three bytes known of a three byte UTF8 unicode character.
2624 step' gst (st, Four c0 c1 c2) = do
2625 r <- step (adaptState gst) st
2629 | not (validate4 c0 c1 c2 c3) -> error "Invalid Sequence"
2630 | otherwise -> Skip (s, YieldPoint $ chr4 c0 c1 c2 c3)
2631 Skip s -> Skip (s, Four c0 c1 c2)
2632 Stop -> error "Input Underflow"
2634 -- This way so that we only need one Yield.
2635 step' _ (s, YieldPoint c) = return $ Yield c (s, FreshPoint)
2637data YieldMany x = None
2640{-# INLINE_NORMAL encodeUtf8 #-}
2641encodeUtf8 :: Monad m => Stream m Char -> Stream m Word8
2642encodeUtf8 (Stream step state) = Stream step' (state, None)
2644 {-# INLINE_LATE step' #-}
2645 step' gst (st, None) = do
2646 r <- step (adaptState gst) st
2651 x | x <= 0x7F -> Skip (s, YieldMany [fromIntegral x])
2652 | x <= 0x7FF -> Skip (s, YieldMany (ord2 c))
2655 then error "Encountered a surrogate"
2656 else Skip (s, YieldMany (ord3 c))
2657 | otherwise -> Skip (s, YieldMany (ord4 c))
2658 Skip s -> Skip (s, None)
2660 step' _ (s, YieldMany []) = return $ Skip (s, None)
2661 step' _ (s, YieldMany (x:xs)) = return $ Yield x (s, YieldMany xs)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list