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 #-}
15#if __GLASGOW_HASKELL__ >= 801
16{-# LANGUAGE TypeApplications #-}
22-- Module : Streamly.Streams.StreamD
23-- Copyright : (c) 2018 Harendra Kumar
24-- Copyright : (c) Roman Leshchinskiy 2008-2010
25-- Copyright : (c) The University of Glasgow, 2009
28-- Maintainer : harendra.kumar@gmail.com
29-- Stability : experimental
32-- Direct style re-implementation of CPS style stream in StreamK module. The
33-- symbol or suffix 'D' in this module denotes the "Direct" style. GHC is able
34-- to INLINE and fuse direct style better, providing better performance than
38-- import qualified Streamly.Streams.StreamD as D
41-- Some of the functions in this file have been adapted from the vector
42-- library, https://hackage.haskell.org/package/vector.
44module Streamly.Streams.StreamD
62 -- ** Specialized Generation
63 -- | Generate a monadic stream from a seed.
75 , enumerateFromStepIntegral
76 , enumerateFromIntegral
77 , enumerateFromThenIntegral
78 , enumerateFromToIntegral
79 , enumerateFromThenToIntegral
81 , enumerateFromStepNum
84 , enumerateFromToFractional
85 , enumerateFromThenToFractional
88 -- | Transform an input structure into a stream.
89 -- | Direct style stream does not support @fromFoldable@.
116 -- ** Specialized Folds
137 -- ** Flattening nested streams
164 -- | Transform a stream into another type.
173 -- ** By folding (scans)
239 -- * Transformation comprehensions
250 -- * UTF8 Encoding / Decoding transformations.
256import Control.Exception (Exception)
257import Control.Monad (void)
258import Control.Monad.Catch (MonadCatch)
259import Control.Monad.IO.Class (MonadIO(..))
260import Control.Monad.Trans (MonadTrans(lift))
261import Data.Bits (shiftR, shiftL, (.|.), (.&.))
262#if __GLASGOW_HASKELL__ >= 801
263import Data.Functor.Identity (Identity)
265import Data.Maybe (fromJust, isJust)
266import Data.Word (Word32)
267import Foreign.Ptr (Ptr)
268import Foreign.Storable (Storable(..))
269import GHC.Base (assert, Char(..), unsafeChr, (-#), (+#), uncheckedIShiftL#,
270 word2Int#, chr#, ord)
271import GHC.IO.Encoding.Failure (isSurrogate)
272import GHC.Types (SPEC(..))
273import GHC.Word (Word8(..))
275 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
276 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
277 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
278 (!!), scanl, scanl1, concatMap, replicate, enumFromTo, concat,
281import qualified Control.Monad.Catch as MC
283import Streamly.Mem.Array.Types (Array(..))
284import Streamly.Fold.Types (Fold(..))
285import Streamly.Pipe.Types (Pipe(..), PipeState(..))
286import Streamly.SVar (MonadAsync, defState, adaptState)
288import Streamly.Streams.StreamD.Type
290import qualified Streamly.Pipe.Types as Pipe
291import qualified Streamly.Mem.Array.Types as A
292import qualified Streamly.Mem.Ring as RB
293import qualified Streamly.Streams.StreamK as K
295------------------------------------------------------------------------------
297------------------------------------------------------------------------------
299-- | An empty 'Stream'.
300{-# INLINE_NORMAL nil #-}
301nil :: Monad m => Stream m a
302nil = Stream (\_ _ -> return Stop) ()
304{-# INLINE_NORMAL consM #-}
305consM :: Monad m => m a -> Stream m a -> Stream m a
306consM m (Stream step state) = Stream step1 Nothing
308 {-# INLINE_LATE step1 #-}
309 step1 _ Nothing = m >>= \x -> return $ Yield x (Just state)
310 step1 gst (Just st) = do
314 Yield a s -> Yield a (Just s)
315 Skip s -> Skip (Just s)
318-- XXX implement in terms of consM?
319-- cons x = consM (return x)
321-- | Can fuse but has O(n^2) complexity.
322{-# INLINE_NORMAL cons #-}
323cons :: Monad m => a -> Stream m a -> Stream m a
324cons x (Stream step state) = Stream step1 Nothing
326 {-# INLINE_LATE step1 #-}
327 step1 _ Nothing = return $ Yield x (Just state)
328 step1 gst (Just st) = do
332 Yield a s -> Yield a (Just s)
333 Skip s -> Skip (Just s)
336-------------------------------------------------------------------------------
338-------------------------------------------------------------------------------
340-- Does not fuse, has the same performance as the StreamK version.
341{-# INLINE_NORMAL uncons #-}
342uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
343uncons (UnStream step state) = go state
346 r <- step defState st
348 Yield x s -> return $ Just (x, Stream step s)
350 Stop -> return Nothing
352------------------------------------------------------------------------------
353-- Generation by unfold
354------------------------------------------------------------------------------
356{-# INLINE_NORMAL unfoldrM #-}
357unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
358unfoldrM next state = Stream step state
360 {-# INLINE_LATE step #-}
364 Just (x, s) -> Yield x s
367{-# INLINE_LATE unfoldr #-}
368unfoldr :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a
369unfoldr f = unfoldrM (return . f)
371------------------------------------------------------------------------------
372-- Specialized Generation
373------------------------------------------------------------------------------
375repeat :: Monad m => a -> Stream m a
376repeat x = Stream (\_ _ -> return $ Yield x ()) ()
378{-# INLINE_NORMAL replicateM #-}
379replicateM :: forall m a. Monad m => Int -> m a -> Stream m a
380replicateM n p = Stream step n
382 {-# INLINE_LATE step #-}
384 | i <= 0 = return Stop
387 return $ Yield x (i - 1)
389-- | For use with flatten
390{-# INLINE replicateGen #-}
391replicateGen :: Monad m => (a, Int) -> m (Step (a, Int) a)
392replicateGen (x, i) = return $
395 else Yield x (x, (i - 1))
397{-# INLINE_NORMAL replicate #-}
398replicate :: Monad m => Int -> a -> Stream m a
399replicate n x = replicateM n (return x)
401-- This would not work properly for floats, therefore we put an Integral
403-- | Can be used to enumerate unbounded integrals. This does not check for
404-- overflow or underflow for bounded integrals.
405{-# INLINE_NORMAL enumerateFromStepIntegral #-}
406enumerateFromStepIntegral :: (Integral a, Monad m) => a -> a -> Stream m a
407enumerateFromStepIntegral from stride =
408 from `seq` stride `seq` Stream step from
410 {-# INLINE_LATE step #-}
411 step _ !x = return $ Yield x $! (x + stride)
413-- We are assuming that "to" is constrained by the type to be within
415{-# INLINE enumerateFromToIntegral #-}
416enumerateFromToIntegral :: (Monad m, Integral a) => a -> a -> Stream m a
417enumerateFromToIntegral from to =
418 takeWhile (<= to) $ enumerateFromStepIntegral from 1
420{-# INLINE enumerateFromIntegral #-}
421enumerateFromIntegral :: (Monad m, Integral a, Bounded a) => a -> Stream m a
422enumerateFromIntegral from = enumerateFromToIntegral from maxBound
424data EnumState a = EnumInit | EnumYield a a a | EnumStop
426{-# INLINE_NORMAL enumerateFromThenToIntegralUp #-}
427enumerateFromThenToIntegralUp
428 :: (Monad m, Integral a)
429 => a -> a -> a -> Stream m a
430enumerateFromThenToIntegralUp from next to = Stream step EnumInit
432 {-# INLINE_LATE step #-}
438 else Yield from EnumStop
439 else -- from <= next <= to
440 let stride = next - from
441 in Skip $ EnumYield from stride (to - stride)
443 step _ (EnumYield x stride toMinus) =
446 then Yield x EnumStop
447 else Yield x $ EnumYield (x + stride) stride toMinus
449 step _ EnumStop = return Stop
451{-# INLINE_NORMAL enumerateFromThenToIntegralDn #-}
452enumerateFromThenToIntegralDn
453 :: (Monad m, Integral a)
454 => a -> a -> a -> Stream m a
455enumerateFromThenToIntegralDn from next to = Stream step EnumInit
457 {-# INLINE_LATE step #-}
459 return $ if to > next
462 else Yield from EnumStop
463 else -- from >= next >= to
464 let stride = next - from
465 in Skip $ EnumYield from stride (to - stride)
467 step _ (EnumYield x stride toMinus) =
470 then Yield x EnumStop
471 else Yield x $ EnumYield (x + stride) stride toMinus
473 step _ EnumStop = return Stop
475{-# INLINE_NORMAL enumerateFromThenToIntegral #-}
476enumerateFromThenToIntegral
477 :: (Monad m, Integral a)
478 => a -> a -> a -> Stream m a
479enumerateFromThenToIntegral from next to
480 | next >= from = enumerateFromThenToIntegralUp from next to
481 | otherwise = enumerateFromThenToIntegralDn from next to
483{-# INLINE_NORMAL enumerateFromThenIntegral #-}
484enumerateFromThenIntegral
485 :: (Monad m, Integral a, Bounded a)
486 => a -> a -> Stream m a
487enumerateFromThenIntegral from next =
489 then enumerateFromThenToIntegralUp from next maxBound
490 else enumerateFromThenToIntegralDn from next minBound
492-- For floating point numbers if the increment is less than the precision then
493-- it just gets lost. Therefore we cannot always increment it correctly by just
495-- 9007199254740992 + 1 + 1 :: Double => 9.007199254740992e15
496-- 9007199254740992 + 2 :: Double => 9.007199254740994e15
498-- Instead we accumulate the increment counter and compute the increment
499-- everytime before adding it to the starting number.
501-- This works for Integrals as well as floating point numbers, but
502-- enumerateFromStepIntegral is faster for integrals.
503{-# INLINE_NORMAL enumerateFromStepNum #-}
504enumerateFromStepNum :: (Monad m, Num a) => a -> a -> Stream m a
505enumerateFromStepNum from stride = Stream step 0
507 {-# INLINE_LATE step #-}
508 step _ !i = return $ (Yield $! (from + i * stride)) $! (i + 1)
510{-# INLINE_NORMAL numFrom #-}
511numFrom :: (Monad m, Num a) => a -> Stream m a
512numFrom from = enumerateFromStepNum from 1
514{-# INLINE_NORMAL numFromThen #-}
515numFromThen :: (Monad m, Num a) => a -> a -> Stream m a
516numFromThen from next = enumerateFromStepNum from (next - from)
518-- We cannot write a general function for Num. The only way to write code
519-- portable between the two is to use a 'Real' constraint and convert between
520-- Fractional and Integral using fromRational which is horribly slow.
521{-# INLINE_NORMAL enumerateFromToFractional #-}
522enumerateFromToFractional
523 :: (Monad m, Fractional a, Ord a)
524 => a -> a -> Stream m a
525enumerateFromToFractional from to =
526 takeWhile (<= to + 1 / 2) $ enumerateFromStepNum from 1
528{-# INLINE_NORMAL enumerateFromThenToFractional #-}
529enumerateFromThenToFractional
530 :: (Monad m, Fractional a, Ord a)
531 => a -> a -> a -> Stream m a
532enumerateFromThenToFractional from next to =
533 takeWhile predicate $ numFromThen from next
535 mid = (next - from) / 2
536 predicate | next >= from = (<= to + mid)
537 | otherwise = (>= to + mid)
539-------------------------------------------------------------------------------
540-- Generation by Conversion
541-------------------------------------------------------------------------------
543{-# INLINE_NORMAL fromIndicesM #-}
544fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
545fromIndicesM gen = Stream step 0
547 {-# INLINE_LATE step #-}
550 return $ Yield x (i + 1)
552{-# INLINE fromIndices #-}
553fromIndices :: Monad m => (Int -> a) -> Stream m a
554fromIndices gen = fromIndicesM (return . gen)
556{-# INLINE_NORMAL generateM #-}
557generateM :: Monad m => Int -> (Int -> m a) -> Stream m a
558generateM n gen = n `seq` Stream step 0
560 {-# INLINE_LATE step #-}
561 step _ i | i < n = do
563 return $ Yield x (i + 1)
564 | otherwise = return Stop
566{-# INLINE generate #-}
567generate :: Monad m => Int -> (Int -> a) -> Stream m a
568generate n gen = generateM n (return . gen)
570-- XXX we need the MonadAsync constraint because of a rewrite rule.
571-- | Convert a list of monadic actions to a 'Stream'
572{-# INLINE_LATE fromListM #-}
573fromListM :: MonadAsync m => [m a] -> Stream m a
574fromListM = Stream step
576 {-# INLINE_LATE step #-}
577 step _ (m:ms) = m >>= \x -> return $ Yield x ms
578 step _ [] = return Stop
580{-# INLINE toStreamD #-}
581toStreamD :: (K.IsStream t, Monad m) => t m a -> Stream m a
582toStreamD = fromStreamK . K.toStream
584------------------------------------------------------------------------------
585-- Elimination by Folds
586------------------------------------------------------------------------------
588------------------------------------------------------------------------------
590------------------------------------------------------------------------------
592{-# INLINE_NORMAL foldr1 #-}
593foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
597 Nothing -> return Nothing
598 Just (h, t) -> fmap Just (foldr f h t)
600------------------------------------------------------------------------------
602------------------------------------------------------------------------------
604{-# INLINE_NORMAL foldlT #-}
605foldlT :: (Monad m, Monad (s m), MonadTrans s)
606 => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
607foldlT fstep begin (Stream step state) = go SPEC begin state
610 r <- lift $ step defState st
612 Yield x s -> go SPEC (fstep acc x) s
613 Skip s -> go SPEC acc s
616-- Note, this is going to have horrible performance, because of the nature of
617-- the stream type (i.e. direct stream vs CPS). Its only for reference, it is
618-- likely be practically unusable.
619{-# INLINE_NORMAL foldlS #-}
621 => (Stream m b -> a -> Stream m b) -> Stream m b -> Stream m a -> Stream m b
622foldlS fstep begin (Stream step state) = Stream step' (Left (state, begin))
624 step' gst (Left (st, acc)) = do
625 r <- step (adaptState gst) st
627 Yield x s -> Skip (Left (s, fstep acc x))
628 Skip s -> Skip (Left (s, acc))
629 Stop -> Skip (Right acc)
631 step' gst (Right (Stream stp stt)) = do
632 r <- stp (adaptState gst) stt
634 Yield x s -> Yield x (Right (Stream stp s))
635 Skip s -> Skip (Right (Stream stp s))
638------------------------------------------------------------------------------
640------------------------------------------------------------------------------
642-- | Run a streaming composition, discard the results.
643{-# INLINE_LATE drain #-}
644drain :: Monad m => Stream m a -> m ()
645-- drain = foldrM (\_ xs -> xs) (return ())
646drain (Stream step state) = go SPEC state
649 r <- step defState st
651 Yield _ s -> go SPEC s
655{-# INLINE_NORMAL null #-}
656null :: Monad m => Stream m a -> m Bool
657null m = foldrM (\_ _ -> return False) (return True) m
660{-# INLINE_NORMAL head #-}
661head :: Monad m => Stream m a -> m (Maybe a)
662head m = foldrM (\x _ -> return (Just x)) (return Nothing) m
664-- Does not fuse, has the same performance as the StreamK version.
665{-# INLINE_NORMAL tail #-}
666tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
667tail (UnStream step state) = go state
670 r <- step defState st
672 Yield _ s -> return (Just $ Stream step s)
674 Stop -> return Nothing
676-- XXX will it fuse? need custom impl?
677{-# INLINE_NORMAL last #-}
678last :: Monad m => Stream m a -> m (Maybe a)
679last = foldl' (\_ y -> Just y) Nothing
681{-# INLINE_NORMAL elem #-}
682elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
683-- elem e m = foldrM (\x xs -> if x == e then return True else xs) (return False) m
684elem e (Stream step state) = go state
687 r <- step defState st
690 | x == e -> return True
695{-# INLINE_NORMAL notElem #-}
696notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
697notElem e s = fmap not (elem e s)
699{-# INLINE_NORMAL all #-}
700all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
701-- all p m = foldrM (\x xs -> if p x then xs else return False) (return True) m
702all p (Stream step state) = go state
705 r <- step defState st
709 | otherwise -> return False
713{-# INLINE_NORMAL any #-}
714any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
715-- any p m = foldrM (\x xs -> if p x then return True else xs) (return False) m
716any p (Stream step state) = go state
719 r <- step defState st
727{-# INLINE_NORMAL maximum #-}
728maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
729maximum (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
741 | acc <= x -> go (Just x) s
742 | otherwise -> go (Just acc) s
743 Skip s -> go (Just acc) s
744 Stop -> return (Just acc)
746{-# INLINE_NORMAL maximumBy #-}
747maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
748maximumBy cmp (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
759 Yield x s -> case cmp acc x of
760 GT -> go (Just acc) s
762 Skip s -> go (Just acc) s
763 Stop -> return (Just acc)
765{-# INLINE_NORMAL minimum #-}
766minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
767minimum (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
779 | acc <= x -> go (Just acc) s
780 | otherwise -> go (Just x) s
781 Skip s -> go (Just acc) s
782 Stop -> return (Just acc)
784{-# INLINE_NORMAL minimumBy #-}
785minimumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
786minimumBy cmp (Stream step state) = go Nothing state
789 r <- step defState st
791 Yield x s -> go (Just x) s
792 Skip s -> go Nothing s
793 Stop -> return Nothing
794 go (Just acc) st = do
795 r <- step defState st
797 Yield x s -> case cmp acc x of
800 Skip s -> go (Just acc) s
801 Stop -> return (Just acc)
803{-# INLINE_NORMAL (!!) #-}
804(!!) :: (Monad m) => Stream m a -> Int -> m (Maybe a)
805(Stream step state) !! i = go i state
808 r <- step defState st
810 Yield x s | n < 0 -> return Nothing
811 | n == 0 -> return $ Just x
812 | otherwise -> go (n - 1) s
814 Stop -> return Nothing
816{-# INLINE_NORMAL lookup #-}
817lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
818lookup e m = foldrM (\(a, b) xs -> if e == a then return (Just b) else xs)
821{-# INLINE_NORMAL findM #-}
822findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
823findM p m = foldrM (\x xs -> p x >>= \r -> if r then return (Just x) else xs)
827find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
828find p = findM (return . p)
830{-# INLINE_NORMAL findIndices #-}
831findIndices :: Monad m => (a -> Bool) -> Stream m a -> Stream m Int
832findIndices p (Stream step state) = Stream step' (state, 0)
834 {-# INLINE_LATE step' #-}
835 step' gst (st, i) = do
836 r <- step (adaptState gst) st
838 Yield x s -> if p x then Yield i (s, i+1) else Skip (s, i+1)
839 Skip s -> Skip (s, i+1)
842{-# INLINE toListRev #-}
843toListRev :: Monad m => Stream m a -> m [a]
844toListRev = foldl' (flip (:)) []
846-- We can implement reverse as:
848-- > reverse = foldlS (flip cons) nil
850-- However, this implementation is unusable because of the horrible performance
851-- of cons. So we just convert it to a list first and then stream from the
854-- XXX Maybe we can use an Array instead of a list here?
855{-# INLINE_NORMAL reverse #-}
856reverse :: Monad m => Stream m a -> Stream m a
857reverse m = Stream step Nothing
859 {-# INLINE_LATE step #-}
862 return $ Skip (Just xs)
863 step _ (Just (x:xs)) = return $ Yield x (Just xs)
864 step _ (Just []) = return Stop
866-- Much faster reverse for Storables
867{-# INLINE_NORMAL reverse' #-}
868reverse' :: forall m a. (MonadIO m, Storable a) => Stream m a -> Stream m a
870-- This commented implementation copies the whole stream into one single array
871-- and then streams from that array, this is 3-4x faster than the chunked code
872-- that follows. Though this could be problematic due to unbounded large
873-- allocations. We need to figure out why the chunked code is slower and if we
874-- can optimize the chunked code to work as fast as this one. It may be a
876import Foreign.ForeignPtr (touchForeignPtr)
877import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
878import Foreign.Ptr (Ptr, plusPtr)
879reverse' m = Stream step Nothing
881 {-# INLINE_LATE step #-}
883 arr <- A.fromStreamD m
884 let p = aEnd arr `plusPtr` negate (sizeOf (undefined :: a))
885 return $ Skip $ Just (aStart arr, p)
887 step _ (Just (start, p)) | p < unsafeForeignPtrToPtr start = return Stop
889 step _ (Just (start, p)) = do
890 let !x = A.unsafeInlineIO $ do
892 touchForeignPtr start
894 next = p `plusPtr` negate (sizeOf (undefined :: a))
895 return $ Yield x (Just (start, next))
902 $ A.fromStreamDArraysOf A.defaultChunkSize m
905------------------------------------------------------------------------------
907------------------------------------------------------------------------------
909{-# INLINE_NORMAL splitSuffixBy' #-}
910splitSuffixBy' :: Monad m
911 => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
912splitSuffixBy' predicate f (Stream step state) =
913 Stream (stepOuter f) (Just state)
917 {-# INLINE_LATE stepOuter #-}
918 stepOuter (Fold fstep initial done) gst (Just st) = do
919 res <- step (adaptState gst) st
925 then done acc' >>= \val -> return $ Yield val (Just s)
928 Skip s -> return $ Skip $ Just s
934 res <- step (adaptState gst) stt
939 then done acc' >>= \val -> return $ Yield val (Just s)
941 Skip s -> go SPEC s acc
942 Stop -> done acc >>= \val -> return $ Yield val Nothing
944 stepOuter _ _ Nothing = return Stop
946{-# INLINE_NORMAL groupsBy #-}
952groupsBy cmp f (Stream step state) = Stream (stepOuter f) (Just state, Nothing)
956 {-# INLINE_LATE stepOuter #-}
957 stepOuter (Fold fstep initial done) gst (Just st, Nothing) = do
958 res <- step (adaptState gst) st
965 Skip s -> return $ Skip $ (Just s, Nothing)
970 go !_ prev stt !acc = do
971 res <- step (adaptState gst) stt
978 else done acc >>= \r -> return $ Yield r (Just s, Just x)
979 Skip s -> go SPEC prev s acc
980 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
982 stepOuter (Fold fstep initial done) gst (Just st, Just prev) = do
984 acc' <- fstep acc prev
989 -- XXX code duplicated from the previous equation
991 res <- step (adaptState gst) stt
998 else done acc >>= \r -> return $ Yield r (Just s, Just x)
999 Skip s -> go SPEC s acc
1000 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1002 stepOuter _ _ (Nothing,_) = return Stop
1004{-# INLINE_NORMAL groupsRollingBy #-}
1005groupsRollingBy :: Monad m
1010groupsRollingBy cmp f (Stream step state) =
1011 Stream (stepOuter f) (Just state, Nothing)
1014 {-# INLINE_LATE stepOuter #-}
1015 stepOuter (Fold fstep initial done) gst (Just st, Nothing) = do
1016 res <- step (adaptState gst) st
1023 Skip s -> return $ Skip $ (Just s, Nothing)
1027 go !_ prev stt !acc = do
1028 res <- step (adaptState gst) stt
1036 done acc >>= \r -> return $ Yield r (Just s, Just x)
1037 Skip s -> go SPEC prev s acc
1038 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1040 stepOuter (Fold fstep initial done) gst (Just st, Just prev') = do
1042 acc' <- fstep acc prev'
1043 go SPEC prev' st acc'
1046 go !_ prevv stt !acc = do
1047 res <- step (adaptState gst) stt
1054 else done acc >>= \r -> return $ Yield r (Just s, Just x)
1055 Skip s -> go SPEC prevv s acc
1056 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1058 stepOuter _ _ (Nothing, _) = return Stop
1060{-# INLINE_NORMAL splitBy #-}
1061splitBy :: Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1062splitBy predicate f (Stream step state) = Stream (step' f) (Just state)
1066 {-# INLINE_LATE step' #-}
1067 step' (Fold fstep initial done) gst (Just st) = initial >>= go SPEC st
1072 res <- step (adaptState gst) stt
1076 then done acc >>= \r -> return $ Yield r (Just s)
1080 Skip s -> go SPEC s acc
1081 Stop -> done acc >>= \r -> return $ Yield r Nothing
1083 step' _ _ Nothing = return Stop
1085{-# INLINE_NORMAL splitSuffixBy #-}
1086splitSuffixBy :: Monad m
1087 => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1088splitSuffixBy predicate f (Stream step state) = Stream (step' f) (Just state)
1092 {-# INLINE_LATE step' #-}
1093 step' (Fold fstep initial done) gst (Just st) = do
1094 res <- step (adaptState gst) st
1099 then done acc >>= \val -> return $ Yield val (Just s)
1104 Skip s -> return $ Skip $ Just s
1110 res <- step (adaptState gst) stt
1114 then done acc >>= \r -> return $ Yield r (Just s)
1118 Skip s -> go SPEC s acc
1119 Stop -> done acc >>= \r -> return $ Yield r Nothing
1121 step' _ _ Nothing = return Stop
1123{-# INLINE_NORMAL wordsBy #-}
1124wordsBy :: Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1125wordsBy predicate f (Stream step state) = Stream (stepOuter f) (Just state)
1129 {-# INLINE_LATE stepOuter #-}
1130 stepOuter (Fold fstep initial done) gst (Just st) = do
1131 res <- step (adaptState gst) st
1135 then return $ Skip (Just s)
1141 Skip s -> return $ Skip $ Just s
1147 res <- step (adaptState gst) stt
1151 then done acc >>= \r -> return $ Yield r (Just s)
1155 Skip s -> go SPEC s acc
1156 Stop -> done acc >>= \r -> return $ Yield r Nothing
1158 stepOuter _ _ Nothing = return Stop
1160-- String search algorithms:
1161-- http://www-igm.univ-mlv.fr/~lecroq/string/index.html
1164-- TODO can we unify the splitting operations using a splitting configuration
1165-- like in the split package.
1167data SplitStyle = Infix | Suffix | Prefix deriving (Eq, Show)
1169data SplitOptions = SplitOptions
1170 { style :: SplitStyle
1171 , withSep :: Bool -- ^ keep the separators in output
1172 -- , compact :: Bool -- ^ treat multiple consecutive separators as one
1173 -- , trimHead :: Bool -- ^ drop blank at head
1174 -- , trimTail :: Bool -- ^ drop blank at tail
1178data SplitOnState s a =
1183 | GO_KARP_RABIN s !(RB.Ring a) !(Ptr a)
1186{-# INLINE_NORMAL splitOn #-}
1188 :: forall m a b. (MonadIO m, Storable a, Enum a, Eq a)
1193splitOn patArr@Array{..} (Fold fstep initial done) (Stream step state) =
1194 Stream stepOuter GO_START
1198 patLen = A.length patArr
1199 maxIndex = patLen - 1
1200 elemBits = sizeOf (undefined :: a) * 8
1202 {-# INLINE_LATE stepOuter #-}
1203 stepOuter _ GO_START =
1205 then return $ Skip $ GO_EMPTY_PAT state
1208 r <- liftIO $ (A.unsafeIndexIO patArr 0)
1209 return $ Skip $ GO_SINGLE_PAT state r
1210 else if sizeOf (undefined :: a) * patLen
1211 <= sizeOf (undefined :: Word)
1212 then return $ Skip $ GO_SHORT_PAT state
1214 (rb, rhead) <- liftIO $ RB.new patLen
1215 return $ Skip $ GO_KARP_RABIN state rb rhead
1217 stepOuter gst (GO_SINGLE_PAT stt pat) = initial >>= go SPEC stt
1222 res <- step (adaptState gst) st
1228 return $ Yield r (GO_SINGLE_PAT s pat)
1229 else fstep acc x >>= go SPEC s
1230 Skip s -> go SPEC s acc
1231 Stop -> done acc >>= \r -> return $ Yield r GO_DONE
1233 stepOuter gst (GO_SHORT_PAT stt) = initial >>= go0 SPEC 0 (0 :: Word) stt
1238 mask = (1 `shiftL` (elemBits * patLen)) - 1
1240 addToWord wrd a = (wrd `shiftL` elemBits) .|. fromIntegral (fromEnum a)
1243 patWord = mask .&. A.foldl' addToWord 0 patArr
1245 go0 !_ !idx wrd st !acc = do
1246 res <- step (adaptState gst) st
1249 let wrd' = addToWord wrd x
1252 if wrd' .&. mask == patWord
1255 return $ Yield r (GO_SHORT_PAT s)
1256 else go1 SPEC wrd' s acc
1257 else go0 SPEC (idx + 1) wrd' s acc
1258 Skip s -> go0 SPEC idx wrd s acc
1261 then go2 wrd idx acc
1263 done acc' >>= \r -> return $ Yield r GO_DONE
1266 go1 !_ wrd st !acc = do
1267 res <- step (adaptState gst) st
1270 let wrd' = addToWord wrd x
1271 old = (mask .&. wrd) `shiftR` (elemBits * (patLen - 1))
1272 acc' <- fstep acc (toEnum $ fromIntegral old)
1273 if wrd' .&. mask == patWord
1274 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1275 else go1 SPEC wrd' s acc'
1276 Skip s -> go1 SPEC wrd s acc
1278 acc' <- go2 wrd patLen acc
1279 done acc' >>= \r -> return $ Yield r GO_DONE
1281 go2 !wrd !n !acc | n > 0 = do
1282 let old = (mask .&. wrd) `shiftR` (elemBits * (n - 1))
1283 fstep acc (toEnum $ fromIntegral old) >>= go2 wrd (n - 1)
1284 go2 _ _ acc = return acc
1286 stepOuter gst (GO_KARP_RABIN stt rb rhead) = do
1287 initial >>= go0 SPEC 0 rhead stt
1291 k = 2891336453 :: Word32
1293 addCksum cksum a = cksum * k + fromIntegral (fromEnum a)
1294 deltaCksum cksum old new =
1295 addCksum cksum new - coeff * fromIntegral (fromEnum old)
1297 -- XXX shall we use a random starting hash or 1 instead of 0?
1298 patHash = A.foldl' addCksum 0 patArr
1301 go0 !_ !idx !rh st !acc = do
1302 res <- step (adaptState gst) st
1305 rh' <- liftIO $ RB.unsafeInsert rb rh x
1308 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1309 let !ringHash = fold addCksum 0 rb
1310 if ringHash == patHash
1311 then go2 SPEC ringHash rh' s acc
1312 else go1 SPEC ringHash rh' s acc
1313 else go0 SPEC (idx + 1) rh' s acc
1314 Skip s -> go0 SPEC idx rh s acc
1316 !acc' <- if idx /= 0
1317 then RB.unsafeFoldRingM rh fstep acc rb
1319 done acc' >>= \r -> return $ Yield r GO_DONE
1321 -- XXX Theoretically this code can do 4 times faster if GHC generates
1322 -- optimal code. If we use just "(cksum' == patHash)" condition it goes
1323 -- 4x faster, as soon as we add the "RB.unsafeEqArray rb v" condition
1324 -- the generated code changes drastically and becomes 4x slower. Need
1325 -- to investigate what is going on with GHC.
1327 go1 !_ !cksum !rh st !acc = do
1328 res <- step (adaptState gst) st
1331 old <- liftIO $ peek rh
1332 let cksum' = deltaCksum cksum old x
1333 acc' <- fstep acc old
1335 if (cksum' == patHash)
1337 rh' <- liftIO (RB.unsafeInsert rb rh x)
1338 go2 SPEC cksum' rh' s acc'
1340 rh' <- liftIO (RB.unsafeInsert rb rh x)
1341 go1 SPEC cksum' rh' s acc'
1342 Skip s -> go1 SPEC cksum rh s acc
1344 acc' <- RB.unsafeFoldRingFullM rh fstep acc rb
1345 done acc' >>= \r -> return $ Yield r GO_DONE
1347 go2 !_ !cksum' !rh' s !acc' = do
1348 if RB.unsafeEqArray rb rh' patArr
1351 return $ Yield r (GO_KARP_RABIN s rb rhead)
1352 else go1 SPEC cksum' rh' s acc'
1354 stepOuter gst (GO_EMPTY_PAT st) = do
1355 res <- step (adaptState gst) st
1360 done acc' >>= \r -> return $ Yield r (GO_EMPTY_PAT s)
1361 Skip s -> return $ Skip (GO_EMPTY_PAT s)
1364 stepOuter _ GO_DONE = return Stop
1366{-# INLINE_NORMAL splitSuffixOn #-}
1368 :: forall m a b. (MonadIO m, Storable a, Enum a, Eq a)
1374splitSuffixOn withSep patArr@Array{..} (Fold fstep initial done)
1375 (Stream step state) =
1376 Stream stepOuter GO_START
1380 patLen = A.length patArr
1381 maxIndex = patLen - 1
1382 elemBits = sizeOf (undefined :: a) * 8
1384 {-# INLINE_LATE stepOuter #-}
1385 stepOuter _ GO_START =
1387 then return $ Skip $ GO_EMPTY_PAT state
1390 r <- liftIO $ (A.unsafeIndexIO patArr 0)
1391 return $ Skip $ GO_SINGLE_PAT state r
1392 else if sizeOf (undefined :: a) * patLen
1393 <= sizeOf (undefined :: Word)
1394 then return $ Skip $ GO_SHORT_PAT state
1396 (rb, rhead) <- liftIO $ RB.new patLen
1397 return $ Skip $ GO_KARP_RABIN state rb rhead
1399 stepOuter gst (GO_SINGLE_PAT stt pat) = do
1400 -- This first part is the only difference between splitOn and
1402 -- If the last element is a separator do not issue a blank segment.
1403 res <- step (adaptState gst) stt
1409 acc' <- if withSep then fstep acc x else return acc
1410 done acc' >>= \r -> return $ Yield r (GO_SINGLE_PAT s pat)
1411 else fstep acc x >>= go SPEC s
1412 Skip s -> return $ Skip $ (GO_SINGLE_PAT s pat)
1417 -- This is identical for splitOn and splitSuffixOn
1419 res <- step (adaptState gst) st
1424 acc' <- if withSep then fstep acc x else return acc
1426 return $ Yield r (GO_SINGLE_PAT s pat)
1427 else fstep acc x >>= go SPEC s
1428 Skip s -> go SPEC s acc
1429 Stop -> done acc >>= \r -> return $ Yield r GO_DONE
1431 stepOuter gst (GO_SHORT_PAT stt) = do
1433 -- Call "initial" only if the stream yields an element, otherwise we
1434 -- may call "initial" but never yield anything. initial may produce a
1435 -- side effect, therefore we will end up doing and discard a side
1440 res <- step (adaptState gst) stt
1444 let wrd' = addToWord wrd x
1445 acc' <- if withSep then fstep acc x else return acc
1448 if wrd' .&. mask == patWord
1449 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1450 else go0 SPEC (idx + 1) wrd' s acc'
1451 else go0 SPEC (idx + 1) wrd' s acc'
1452 Skip s -> return $ Skip (GO_SHORT_PAT s)
1458 mask = (1 `shiftL` (elemBits * patLen)) - 1
1460 addToWord wrd a = (wrd `shiftL` elemBits) .|. fromIntegral (fromEnum a)
1463 patWord = mask .&. A.foldl' addToWord 0 patArr
1465 go0 !_ !idx wrd st !acc = do
1466 res <- step (adaptState gst) st
1469 let wrd' = addToWord wrd x
1470 acc' <- if withSep then fstep acc x else return acc
1473 if wrd' .&. mask == patWord
1476 return $ Yield r (GO_SHORT_PAT s)
1477 else go1 SPEC wrd' s acc'
1478 else go0 SPEC (idx + 1) wrd' s acc'
1479 Skip s -> go0 SPEC idx wrd s acc
1481 if (idx == maxIndex) && (wrd .&. mask == patWord)
1484 acc' <- if idx /= 0 && not withSep
1485 then go2 wrd idx acc
1487 done acc' >>= \r -> return $ Yield r GO_DONE
1490 go1 !_ wrd st !acc = do
1491 res <- step (adaptState gst) st
1494 let wrd' = addToWord wrd x
1495 old = (mask .&. wrd) `shiftR` (elemBits * (patLen - 1))
1498 else fstep acc (toEnum $ fromIntegral old)
1499 if wrd' .&. mask == patWord
1500 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1501 else go1 SPEC wrd' s acc'
1502 Skip s -> go1 SPEC wrd s acc
1504 -- If the last sequence is a separator do not issue a blank
1506 if wrd .&. mask == patWord
1511 else go2 wrd patLen acc
1512 done acc' >>= \r -> return $ Yield r GO_DONE
1514 go2 !wrd !n !acc | n > 0 = do
1515 let old = (mask .&. wrd) `shiftR` (elemBits * (n - 1))
1516 fstep acc (toEnum $ fromIntegral old) >>= go2 wrd (n - 1)
1517 go2 _ _ acc = return acc
1519 stepOuter gst (GO_KARP_RABIN stt rb rhead) = do
1521 res <- step (adaptState gst) stt
1525 acc' <- if withSep then fstep acc x else return acc
1526 rh' <- liftIO (RB.unsafeInsert rb rhead x)
1529 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1530 let !ringHash = fold addCksum 0 rb
1531 if ringHash == patHash
1532 then go2 SPEC ringHash rh' s acc'
1533 else go0 SPEC (idx + 1) rh' s acc'
1534 else go0 SPEC (idx + 1) rh' s acc'
1535 Skip s -> return $ Skip (GO_KARP_RABIN s rb rhead)
1540 k = 2891336453 :: Word32
1542 addCksum cksum a = cksum * k + fromIntegral (fromEnum a)
1543 deltaCksum cksum old new =
1544 addCksum cksum new - coeff * fromIntegral (fromEnum old)
1546 -- XXX shall we use a random starting hash or 1 instead of 0?
1547 patHash = A.foldl' addCksum 0 patArr
1550 go0 !_ !idx !rh st !acc = do
1551 res <- step (adaptState gst) st
1554 acc' <- if withSep then fstep acc x else return acc
1555 rh' <- liftIO (RB.unsafeInsert rb rh x)
1558 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1559 let !ringHash = fold addCksum 0 rb
1560 if ringHash == patHash
1561 then go2 SPEC ringHash rh' s acc'
1562 else go1 SPEC ringHash rh' s acc'
1563 else go0 SPEC (idx + 1) rh' s acc'
1564 Skip s -> go0 SPEC idx rh s acc
1566 -- do not issue a blank segment when we end at pattern
1567 if (idx == maxIndex) && RB.unsafeEqArray rb rh patArr
1570 !acc' <- if idx /= 0 && not withSep
1571 then RB.unsafeFoldRingM rh fstep acc rb
1573 done acc' >>= \r -> return $ Yield r GO_DONE
1575 -- XXX Theoretically this code can do 4 times faster if GHC generates
1576 -- optimal code. If we use just "(cksum' == patHash)" condition it goes
1577 -- 4x faster, as soon as we add the "RB.unsafeEqArray rb v" condition
1578 -- the generated code changes drastically and becomes 4x slower. Need
1579 -- to investigate what is going on with GHC.
1581 go1 !_ !cksum !rh st !acc = do
1582 res <- step (adaptState gst) st
1585 old <- liftIO $ peek rh
1586 let cksum' = deltaCksum cksum old x
1591 if (cksum' == patHash)
1593 rh' <- liftIO (RB.unsafeInsert rb rh x)
1594 go2 SPEC cksum' rh' s acc'
1596 rh' <- liftIO (RB.unsafeInsert rb rh x)
1597 go1 SPEC cksum' rh' s acc'
1598 Skip s -> go1 SPEC cksum rh s acc
1600 if RB.unsafeEqArray rb rh patArr
1605 else RB.unsafeFoldRingFullM rh fstep acc rb
1606 done acc' >>= \r -> return $ Yield r GO_DONE
1608 go2 !_ !cksum' !rh' s !acc' = do
1609 if RB.unsafeEqArray rb rh' patArr
1612 return $ Yield r (GO_KARP_RABIN s rb rhead)
1613 else go1 SPEC cksum' rh' s acc'
1615 stepOuter gst (GO_EMPTY_PAT st) = do
1616 res <- step (adaptState gst) st
1621 done acc' >>= \r -> return $ Yield r (GO_EMPTY_PAT s)
1622 Skip s -> return $ Skip (GO_EMPTY_PAT s)
1625 stepOuter _ GO_DONE = return Stop
1627------------------------------------------------------------------------------
1629------------------------------------------------------------------------------
1631{-# INLINE_NORMAL isPrefixOf #-}
1632isPrefixOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
1633isPrefixOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
1635 go (sa, sb, Nothing) = do
1636 r <- stepa defState sa
1638 Yield x sa' -> go (sa', sb, Just x)
1639 Skip sa' -> go (sa', sb, Nothing)
1642 go (sa, sb, Just x) = do
1643 r <- stepb defState sb
1647 then go (sa, sb', Nothing)
1649 Skip sb' -> go (sa, sb', Just x)
1650 Stop -> return False
1652{-# INLINE_NORMAL isSubsequenceOf #-}
1653isSubsequenceOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
1654isSubsequenceOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
1656 go (sa, sb, Nothing) = do
1657 r <- stepa defState sa
1659 Yield x sa' -> go (sa', sb, Just x)
1660 Skip sa' -> go (sa', sb, Nothing)
1663 go (sa, sb, Just x) = do
1664 r <- stepb defState sb
1668 then go (sa, sb', Nothing)
1669 else go (sa, sb', Just x)
1670 Skip sb' -> go (sa, sb', Just x)
1671 Stop -> return False
1673{-# INLINE_NORMAL stripPrefix #-}
1676 => Stream m a -> Stream m a -> m (Maybe (Stream m a))
1677stripPrefix (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
1679 go (sa, sb, Nothing) = do
1680 r <- stepa defState sa
1682 Yield x sa' -> go (sa', sb, Just x)
1683 Skip sa' -> go (sa', sb, Nothing)
1684 Stop -> return $ Just (Stream stepb sb)
1686 go (sa, sb, Just x) = do
1687 r <- stepb defState sb
1691 then go (sa, sb', Nothing)
1693 Skip sb' -> go (sa, sb', Just x)
1694 Stop -> return Nothing
1696------------------------------------------------------------------------------
1698------------------------------------------------------------------------------
1700-- | Execute a monadic action for each element of the 'Stream'
1701{-# INLINE_NORMAL mapM_ #-}
1702mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
1703mapM_ m = drain . mapM m
1705------------------------------------------------------------------------------
1707------------------------------------------------------------------------------
1709-- | Run a side effect before the stream yields its first element.
1710{-# INLINE_NORMAL before #-}
1711before :: Monad m => m b -> Stream m a -> Stream m a
1712before action (Stream step state) = Stream step' Nothing
1716 {-# INLINE_LATE step' #-}
1717 step' _ Nothing = action >> return (Skip (Just state))
1719 step' gst (Just st) = do
1722 Yield x s -> return $ Yield x (Just s)
1723 Skip s -> return $ Skip (Just s)
1726-- | Run a side effect whenever the stream stops normally.
1727{-# INLINE_NORMAL after #-}
1728after :: Monad m => m b -> Stream m a -> Stream m a
1729after action (Stream step state) = Stream step' state
1733 {-# INLINE_LATE step' #-}
1737 Yield x s -> return $ Yield x s
1738 Skip s -> return $ Skip s
1739 Stop -> action >> return Stop
1741-- XXX These combinators are expensive due to the call to
1742-- onException/handle/try on each step. Therefore, when possible, they should
1743-- be called in an outer loop where we perform less iterations. For example, we
1744-- cannot call them on each iteration in a char stream, instead we can call
1745-- them when doing an IO on an array.
1747-- XXX For high performance error checks in busy streams we may need another
1748-- Error constructor in step.
1750-- | Run a side effect whenever the stream aborts due to an exception. The
1751-- exception is not caught simply rethrown.
1752{-# INLINE_NORMAL onException #-}
1753onException :: MonadCatch m => m b -> Stream m a -> Stream m a
1754onException action (Stream step state) = Stream step' state
1758 {-# INLINE_LATE step' #-}
1760 res <- step gst st `MC.onException` action
1762 Yield x s -> return $ Yield x s
1763 Skip s -> return $ Skip s
1766-- | Run a side effect whenever the stream stops normally or aborts due to an
1768{-# INLINE finally #-}
1769finally :: MonadCatch m => m b -> Stream m a -> Stream m a
1770finally action xs = after action $ onException action xs
1772-- XXX bracket is like concatMap, it generates a stream and then flattens it.
1773-- Like concatMap it has 10x worse performance compared to linear fused
1776-- | Run the first action before the stream starts and remember its output,
1777-- generate a stream using the output, run the second action using the
1778-- remembered value as an argument whenever the stream ends normally or due to
1780{-# INLINE_NORMAL bracket #-}
1781bracket :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
1782bracket bef aft bet = Stream step' Nothing
1786 {-# INLINE_LATE step' #-}
1787 step' _ Nothing = bef >>= \x -> return (Skip (Just (bet x, x)))
1789 -- NOTE: It is important to use UnStream instead of the Stream pattern
1790 -- here, otherwise we get huge perf degradation, see note in concatMap.
1791 step' gst (Just (UnStream step state, v)) = do
1792 res <- step gst state `MC.onException` aft v
1794 Yield x s -> return $ Yield x (Just (Stream step s, v))
1795 Skip s -> return $ Skip (Just (Stream step s, v))
1796 Stop -> aft v >> return Stop
1798-- | When evaluating a stream if an exception occurs, stream evaluation aborts
1799-- and the specified exception handler is run with the exception as argument.
1800{-# INLINE_NORMAL handle #-}
1801handle :: (MonadCatch m, Exception e) => (e -> m a) -> Stream m a -> Stream m a
1802handle f (Stream step state) = Stream step' (Just state)
1806 {-# INLINE_LATE step' #-}
1807 step' gst (Just st) = do
1808 res <- MC.try $ step gst st
1810 Left e -> f e >>= \x -> return (Yield x Nothing)
1811 Right r -> case r of
1812 Yield x s -> return $ Yield x (Just s)
1813 Skip s -> return $ Skip (Just s)
1816 step' _ Nothing = return Stop
1818-------------------------------------------------------------------------------
1819-- General transformation
1820-------------------------------------------------------------------------------
1822{-# INLINE_NORMAL transform #-}
1823transform :: Monad m => Pipe m a b -> Stream m a -> Stream m b
1824transform (Pipe pstep1 pstep2 pstate) (Stream step state) =
1825 Stream step' (Consume pstate, state)
1829 {-# INLINE_LATE step' #-}
1831 step' gst (Consume pst, st) = pst `seq` do
1832 r <- step (adaptState gst) st
1837 Pipe.Yield b pst' -> return $ Yield b (pst', s)
1838 Pipe.Continue pst' -> return $ Skip (pst', s)
1839 Skip s -> return $ Skip (Consume pst, s)
1842 step' _ (Produce pst, st) = pst `seq` do
1845 Pipe.Yield b pst' -> return $ Yield b (pst', st)
1846 Pipe.Continue pst' -> return $ Skip (pst', st)
1848------------------------------------------------------------------------------
1849-- Transformation by Folding (Scans)
1850------------------------------------------------------------------------------
1852------------------------------------------------------------------------------
1854------------------------------------------------------------------------------
1856-- XXX Is a prescan useful, discarding the last step does not sound useful? I
1857-- am not sure about the utility of this function, so this is implemented but
1858-- not exposed. We can expose it if someone provides good reasons why this is
1861-- XXX We have to execute the stream one step ahead to know that we are at the
1862-- last step. The vector implementation of prescan executes the last fold step
1863-- but does not yield the result. This means we have executed the effect but
1864-- discarded value. This does not sound right. In this implementation we are
1865-- not executing the last fold step.
1866{-# INLINE_NORMAL prescanlM' #-}
1867prescanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
1868prescanlM' f mz (Stream step state) = Stream step' (state, mz)
1870 {-# INLINE_LATE step' #-}
1871 step' gst (st, prev) = do
1872 r <- step (adaptState gst) st
1876 return $ Yield acc (s, f acc x)
1877 Skip s -> return $ Skip (s, prev)
1880{-# INLINE prescanl' #-}
1881prescanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
1882prescanl' f z = prescanlM' (\a b -> return (f a b)) (return z)
1884------------------------------------------------------------------------------
1885-- Monolithic postscans (postscan followed by a map)
1886------------------------------------------------------------------------------
1888-- The performance of a modular postscan followed by a map seems to be
1889-- equivalent to this monolithic scan followed by map therefore we may not need
1890-- this implementation. We just have it for performance comparison and in case
1891-- modular version does not perform well in some situation.
1893{-# INLINE_NORMAL postscanlMx' #-}
1894postscanlMx' :: Monad m
1895 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
1896postscanlMx' fstep begin done (Stream step state) = do
1897 Stream step' (state, begin)
1899 {-# INLINE_LATE step' #-}
1900 step' gst (st, acc) = do
1901 r <- step (adaptState gst) st
1907 v `seq` y `seq` return (Yield v (s, return y))
1908 Skip s -> return $ Skip (s, acc)
1911{-# INLINE_NORMAL postscanlx' #-}
1912postscanlx' :: Monad m
1913 => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
1914postscanlx' fstep begin done s =
1915 postscanlMx' (\b a -> return (fstep b a)) (return begin) (return . done) s
1917-- XXX do we need consM strict to evaluate the begin value?
1918{-# INLINE scanlMx' #-}
1920 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
1921scanlMx' fstep begin done s =
1922 (begin >>= \x -> x `seq` done x) `consM` postscanlMx' fstep begin done s
1924{-# INLINE scanlx' #-}
1926 => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
1927scanlx' fstep begin done s =
1928 scanlMx' (\b a -> return (fstep b a)) (return begin) (return . done) s
1930------------------------------------------------------------------------------
1932------------------------------------------------------------------------------
1934{-# INLINE_NORMAL postscanlM' #-}
1935postscanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
1936postscanlM' fstep begin (Stream step state) =
1937 begin `seq` Stream step' (state, begin)
1939 {-# INLINE_LATE step' #-}
1940 step' gst (st, acc) = acc `seq` do
1941 r <- step (adaptState gst) st
1945 y `seq` return (Yield y (s, y))
1946 Skip s -> return $ Skip (s, acc)
1949{-# INLINE_NORMAL postscanl' #-}
1950postscanl' :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
1951postscanl' f = postscanlM' (\a b -> return (f a b))
1953{-# INLINE_NORMAL postscanlM #-}
1954postscanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
1955postscanlM fstep begin (Stream step state) = Stream step' (state, begin)
1957 {-# INLINE_LATE step' #-}
1958 step' gst (st, acc) = do
1959 r <- step (adaptState gst) st
1963 return (Yield y (s, y))
1964 Skip s -> return $ Skip (s, acc)
1967{-# INLINE_NORMAL postscanl #-}
1968postscanl :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
1969postscanl f = postscanlM (\a b -> return (f a b))
1971{-# INLINE_NORMAL scanlM' #-}
1972scanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
1973scanlM' fstep begin s = begin `seq` (begin `cons` postscanlM' fstep begin s)
1975{-# INLINE scanl' #-}
1976scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
1977scanl' f = scanlM' (\a b -> return (f a b))
1979{-# INLINE_NORMAL scanlM #-}
1980scanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
1981scanlM fstep begin s = begin `cons` postscanlM fstep begin s
1984scanl :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
1985scanl f = scanlM (\a b -> return (f a b))
1987{-# INLINE_NORMAL scanl1M #-}
1988scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
1989scanl1M fstep (Stream step state) = Stream step' (state, Nothing)
1991 {-# INLINE_LATE step' #-}
1992 step' gst (st, Nothing) = do
1995 Yield x s -> return $ Yield x (s, Just x)
1996 Skip s -> return $ Skip (s, Nothing)
1999 step' gst (st, Just acc) = do
2004 return $ Yield z (s, Just z)
2005 Skip s -> return $ Skip (s, Just acc)
2008{-# INLINE scanl1 #-}
2009scanl1 :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
2010scanl1 f = scanl1M (\x y -> return (f x y))
2012{-# INLINE_NORMAL scanl1M' #-}
2013scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
2014scanl1M' fstep (Stream step state) = Stream step' (state, Nothing)
2016 {-# INLINE_LATE step' #-}
2017 step' gst (st, Nothing) = do
2020 Yield x s -> x `seq` return $ Yield x (s, Just x)
2021 Skip s -> return $ Skip (s, Nothing)
2024 step' gst (st, Just acc) = acc `seq` do
2029 z `seq` return $ Yield z (s, Just z)
2030 Skip s -> return $ Skip (s, Just acc)
2033{-# INLINE scanl1' #-}
2034scanl1' :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
2035scanl1' f = scanl1M' (\x y -> return (f x y))
2038tap :: Monad m => Fold m a b -> Stream m a -> Stream m a
2039tap (Fold fstep initial extract) (Stream step state) = Stream step' Nothing
2043 step' _ Nothing = do
2045 return $ Skip (Just (r, state))
2047 step' gst (Just (acc, st)) = do
2052 return $ Yield x (Just (acc', s))
2053 Skip s -> return $ Skip (Just (acc, s))
2058-------------------------------------------------------------------------------
2060-------------------------------------------------------------------------------
2062{-# INLINE_NORMAL takeWhileM #-}
2063takeWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
2064takeWhileM f (Stream step state) = Stream step' state
2066 {-# INLINE_LATE step' #-}
2072 return $ if b then Yield x s else Stop
2073 Skip s -> return $ Skip s
2076{-# INLINE takeWhile #-}
2077takeWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
2078takeWhile f = takeWhileM (return . f)
2080{-# INLINE_NORMAL drop #-}
2081drop :: Monad m => Int -> Stream m a -> Stream m a
2082drop n (Stream step state) = Stream step' (state, Just n)
2084 {-# INLINE_LATE step' #-}
2085 step' gst (st, Just i)
2090 Yield _ s -> Skip (s, Just (i - 1))
2091 Skip s -> Skip (s, Just i)
2093 | otherwise = return $ Skip (st, Nothing)
2095 step' gst (st, Nothing) = do
2099 Yield x s -> Yield x (s, Nothing)
2100 Skip s -> Skip (s, Nothing)
2103data DropWhileState s a
2105 | DropWhileYield a s
2108{-# INLINE_NORMAL dropWhileM #-}
2109dropWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
2110dropWhileM f (Stream step state) = Stream step' (DropWhileDrop state)
2112 {-# INLINE_LATE step' #-}
2113 step' gst (DropWhileDrop st) = do
2119 then return $ Skip (DropWhileDrop s)
2120 else return $ Skip (DropWhileYield x s)
2121 Skip s -> return $ Skip (DropWhileDrop s)
2124 step' gst (DropWhileNext st) = do
2127 Yield x s -> return $ Skip (DropWhileYield x s)
2128 Skip s -> return $ Skip (DropWhileNext s)
2131 step' _ (DropWhileYield x st) = return $ Yield x (DropWhileNext st)
2133{-# INLINE dropWhile #-}
2134dropWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
2135dropWhile f = dropWhileM (return . f)
2137{-# INLINE_NORMAL filterM #-}
2138filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
2139filterM f (Stream step state) = Stream step' state
2141 {-# INLINE_LATE step' #-}
2150 Skip s -> return $ Skip s
2153{-# INLINE filter #-}
2154filter :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
2155filter f = filterM (return . f)
2157{-# INLINE_NORMAL uniq #-}
2158uniq :: (Eq a, Monad m) => Stream m a -> Stream m a
2159uniq (Stream step state) = Stream step' (Nothing, state)
2161 {-# INLINE_LATE step' #-}
2162 step' gst (Nothing, st) = do
2165 Yield x s -> return $ Yield x (Just x, s)
2166 Skip s -> return $ Skip (Nothing, s)
2168 step' gst (Just x, st) = do
2171 Yield y s | x == y -> return $ Skip (Just x, s)
2172 | otherwise -> return $ Yield y (Just y, s)
2173 Skip s -> return $ Skip (Just x, s)
2176------------------------------------------------------------------------------
2177-- Transformation by Mapping
2178------------------------------------------------------------------------------
2180{-# INLINE_NORMAL sequence #-}
2181sequence :: Monad m => Stream m (m a) -> Stream m a
2182sequence (Stream step state) = Stream step' state
2184 {-# INLINE_LATE step' #-}
2186 r <- step (adaptState gst) st
2188 Yield x s -> x >>= \a -> return (Yield a s)
2189 Skip s -> return $ Skip s
2192------------------------------------------------------------------------------
2194------------------------------------------------------------------------------
2196data LoopState x s = FirstYield s
2197 | InterspersingYield s
2200{-# INLINE_NORMAL intersperseM #-}
2201intersperseM :: Monad m => m a -> Stream m a -> Stream m a
2202intersperseM m (Stream step state) = Stream step' (FirstYield state)
2204 {-# INLINE_LATE step' #-}
2205 step' gst (FirstYield st) = do
2209 Yield x s -> Skip (YieldAndCarry x s)
2210 Skip s -> Skip (FirstYield s)
2213 step' gst (InterspersingYield st) = do
2218 return $ Yield a (YieldAndCarry x s)
2219 Skip s -> return $ Skip $ InterspersingYield s
2222 step' _ (YieldAndCarry x st) = return $ Yield x (InterspersingYield st)
2227 | SuffixYield a (SuffixState s a)
2229{-# INLINE_NORMAL insertAfterEach #-}
2230insertAfterEach :: forall m a. Monad m => m a -> Stream m a -> Stream m a
2231insertAfterEach action (Stream step state) = Stream step' (SuffixElem state)
2233 {-# INLINE_LATE step' #-}
2234 step' gst (SuffixElem st) = do
2237 Yield x s -> Skip (SuffixYield x (SuffixSuffix s))
2238 Skip s -> Skip (SuffixElem s)
2241 step' _ (SuffixSuffix st) = do
2242 action >>= \r -> return $ Skip (SuffixYield r (SuffixElem st))
2244 step' _ (SuffixYield x next) = return $ Yield x next
2246{-# INLINE intersperse #-}
2247intersperse :: Monad m => a -> Stream m a -> Stream m a
2248intersperse a = intersperseM (return a)
2250{-# INLINE_NORMAL insertBy #-}
2251insertBy :: Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
2252insertBy cmp a (Stream step state) = Stream step' (state, False, Nothing)
2254 {-# INLINE_LATE step' #-}
2255 step' gst (st, False, _) = do
2258 Yield x s -> case cmp a x of
2259 GT -> return $ Yield x (s, False, Nothing)
2260 _ -> return $ Yield a (s, True, Just x)
2261 Skip s -> return $ Skip (s, False, Nothing)
2262 Stop -> return $ Yield a (st, True, Nothing)
2264 step' _ (_, True, Nothing) = return Stop
2266 step' gst (st, True, Just prev) = do
2269 Yield x s -> return $ Yield prev (s, True, Just x)
2270 Skip s -> return $ Skip (s, True, Just prev)
2271 Stop -> return $ Yield prev (st, True, Nothing)
2273------------------------------------------------------------------------------
2275------------------------------------------------------------------------------
2277{-# INLINE_NORMAL deleteBy #-}
2278deleteBy :: Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a
2279deleteBy eq x (Stream step state) = Stream step' (state, False)
2281 {-# INLINE_LATE step' #-}
2282 step' gst (st, False) = do
2285 Yield y s -> return $
2286 if eq x y then Skip (s, True) else Yield y (s, False)
2287 Skip s -> return $ Skip (s, False)
2290 step' gst (st, True) = do
2293 Yield y s -> return $ Yield y (s, True)
2294 Skip s -> return $ Skip (s, True)
2297------------------------------------------------------------------------------
2298-- Transformation by Map and Filter
2299------------------------------------------------------------------------------
2301-- XXX Will this always fuse properly?
2302{-# INLINE_NORMAL mapMaybe #-}
2303mapMaybe :: Monad m => (a -> Maybe b) -> Stream m a -> Stream m b
2304mapMaybe f = fmap fromJust . filter isJust . map f
2306{-# INLINE_NORMAL mapMaybeM #-}
2307mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b
2308mapMaybeM f = fmap fromJust . filter isJust . mapM f
2310------------------------------------------------------------------------------
2312------------------------------------------------------------------------------
2314{-# INLINE_NORMAL indexed #-}
2315indexed :: Monad m => Stream m a -> Stream m (Int, a)
2316indexed (Stream step state) = Stream step' (state, 0)
2318 {-# INLINE_LATE step' #-}
2319 step' gst (st, i) = i `seq` do
2320 r <- step (adaptState gst) st
2322 Yield x s -> return $ Yield (i, x) (s, i+1)
2323 Skip s -> return $ Skip (s, i)
2326{-# INLINE_NORMAL indexedR #-}
2327indexedR :: Monad m => Int -> Stream m a -> Stream m (Int, a)
2328indexedR m (Stream step state) = Stream step' (state, m)
2330 {-# INLINE_LATE step' #-}
2331 step' gst (st, i) = i `seq` do
2332 r <- step (adaptState gst) st
2334 Yield x s -> let i' = i - 1
2335 in return $ Yield (i, x) (s, i')
2336 Skip s -> return $ Skip (s, i)
2339{-# INLINE_NORMAL zipWithM #-}
2341 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
2342zipWithM f (Stream stepa ta) (Stream stepb tb) = Stream step (ta, tb, Nothing)
2344 {-# INLINE_LATE step #-}
2345 step gst (sa, sb, Nothing) = do
2346 r <- stepa (adaptState gst) sa
2349 Yield x sa' -> Skip (sa', sb, Just x)
2350 Skip sa' -> Skip (sa', sb, Nothing)
2353 step gst (sa, sb, Just x) = do
2354 r <- stepb (adaptState gst) sb
2358 return $ Yield z (sa, sb', Nothing)
2359 Skip sb' -> return $ Skip (sa, sb', Just x)
2362#if __GLASGOW_HASKELL__ >= 801
2363{-# RULES "zipWithM xs xs"
2364 forall f xs. zipWithM @Identity f xs xs = mapM (\x -> f x x) xs #-}
2367{-# INLINE zipWith #-}
2368zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
2369zipWith f = zipWithM (\a b -> return (f a b))
2371------------------------------------------------------------------------------
2373------------------------------------------------------------------------------
2375{-# INLINE_NORMAL mergeByM #-}
2378 => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
2379mergeByM cmp (Stream stepa ta) (Stream stepb tb) =
2380 Stream step (Just ta, Just tb, Nothing, Nothing)
2382 {-# INLINE_LATE step #-}
2384 -- one of the values is missing, and the corresponding stream is running
2385 step gst (Just sa, sb, Nothing, b) = do
2388 Yield a sa' -> Skip (Just sa', sb, Just a, b)
2389 Skip sa' -> Skip (Just sa', sb, Nothing, b)
2390 Stop -> Skip (Nothing, sb, Nothing, b)
2392 step gst (sa, Just sb, a, Nothing) = do
2395 Yield b sb' -> Skip (sa, Just sb', a, Just b)
2396 Skip sb' -> Skip (sa, Just sb', a, Nothing)
2397 Stop -> Skip (sa, Nothing, a, Nothing)
2399 -- both the values are available
2400 step _ (sa, sb, Just a, Just b) = do
2402 return $ case res of
2403 GT -> Yield b (sa, sb, Just a, Nothing)
2404 _ -> Yield a (sa, sb, Nothing, Just b)
2406 -- one of the values is missing, corresponding stream is done
2407 step _ (Nothing, sb, Nothing, Just b) =
2408 return $ Yield b (Nothing, sb, Nothing, Nothing)
2410 step _ (sa, Nothing, Just a, Nothing) =
2411 return $ Yield a (sa, Nothing, Nothing, Nothing)
2413 step _ (Nothing, Nothing, Nothing, Nothing) = return Stop
2415{-# INLINE mergeBy #-}
2418 => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
2419mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
2421------------------------------------------------------------------------------
2422-- Transformation comprehensions
2423------------------------------------------------------------------------------
2425{-# INLINE_NORMAL the #-}
2426the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
2427the (Stream step state) = go state
2430 r <- step defState st
2432 Yield x s -> go' x s
2434 Stop -> return Nothing
2436 r <- step defState st
2438 Yield x s | x == n -> go' n s
2439 | otherwise -> return Nothing
2441 Stop -> return (Just n)
2443--------------------------------------------------------------------------------
2444-- UTF8 Encoding / Decoding
2445--------------------------------------------------------------------------------
2447-- UTF-8 primitives, Lifted from GHC.IO.Encoding.UTF8.
2449ord2 :: Char -> [Word8]
2450ord2 c = assert (n >= 0x80 && n <= 0x07ff) [x1, x2]
2453 x1 = fromIntegral $ (n `shiftR` 6) + 0xC0
2454 x2 = fromIntegral $ (n .&. 0x3F) + 0x80
2456ord3 :: Char -> [Word8]
2457ord3 c = assert (n >= 0x0800 && n <= 0xffff) [x1, x2, x3]
2460 x1 = fromIntegral $ (n `shiftR` 12) + 0xE0
2461 x2 = fromIntegral $ ((n `shiftR` 6) .&. 0x3F) + 0x80
2462 x3 = fromIntegral $ (n .&. 0x3F) + 0x80
2464ord4 :: Char -> [Word8]
2465ord4 c = assert (n >= 0x10000) [x1, x2, x3, x4]
2468 x1 = fromIntegral $ (n `shiftR` 18) + 0xF0
2469 x2 = fromIntegral $ ((n `shiftR` 12) .&. 0x3F) + 0x80
2470 x3 = fromIntegral $ ((n `shiftR` 6) .&. 0x3F) + 0x80
2471 x4 = fromIntegral $ (n .&. 0x3F) + 0x80
2474chr2 :: Word8 -> Word8 -> Char
2475chr2 (W8# x1#) (W8# x2#) = C# (chr# (z1# +# z2#))
2477 !y1# = word2Int# x1#
2478 !y2# = word2Int# x2#
2479 !z1# = uncheckedIShiftL# (y1# -# 192#) 6#
2483chr3 :: Word8 -> Word8 -> Word8 -> Char
2484chr3 (W8# x1#) (W8# x2#) (W8# x3#) = C# (chr# (z1# +# z2# +# z3#))
2486 !y1# = word2Int# x1#
2487 !y2# = word2Int# x2#
2488 !y3# = word2Int# x3#
2489 !z1# = uncheckedIShiftL# (y1# -# 224#) 12#
2490 !z2# = uncheckedIShiftL# (y2# -# 128#) 6#
2494chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char
2495chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) =
2496 C# (chr# (z1# +# z2# +# z3# +# z4#))
2498 !y1# = word2Int# x1#
2499 !y2# = word2Int# x2#
2500 !y3# = word2Int# x3#
2501 !y4# = word2Int# x4#
2502 !z1# = uncheckedIShiftL# (y1# -# 240#) 18#
2503 !z2# = uncheckedIShiftL# (y2# -# 128#) 12#
2504 !z3# = uncheckedIShiftL# (y3# -# 128#) 6#
2507{-# INLINE between #-}
2509 Word8 -- ^ byte to check
2510 -> Word8 -- ^ lower bound
2511 -> Word8 -- ^ upper bound
2513between x y z = x >= y && x <= z
2515{-# INLINE validate3 #-}
2516validate3 :: Word8 -> Word8 -> Word8 -> Bool
2517validate3 x1 x2 x3 = validate3_1 ||
2522 validate3_1 = (x1 == 0xE0) &&
2523 between x2 0xA0 0xBF &&
2524 between x3 0x80 0xBF
2525 validate3_2 = between x1 0xE1 0xEC &&
2526 between x2 0x80 0xBF &&
2527 between x3 0x80 0xBF
2528 validate3_3 = x1 == 0xED &&
2529 between x2 0x80 0x9F &&
2530 between x3 0x80 0xBF
2531 validate3_4 = between x1 0xEE 0xEF &&
2532 between x2 0x80 0xBF &&
2533 between x3 0x80 0xBF
2535{-# INLINE validate4 #-}
2536validate4 :: Word8 -> Word8 -> Word8 -> Word8 -> Bool
2537validate4 x1 x2 x3 x4 = validate4_1 ||
2541 validate4_1 = x1 == 0xF0 &&
2542 between x2 0x90 0xBF &&
2543 between x3 0x80 0xBF &&
2544 between x4 0x80 0xBF
2545 validate4_2 = between x1 0xF1 0xF3 &&
2546 between x2 0x80 0xBF &&
2547 between x3 0x80 0xBF &&
2548 between x4 0x80 0xBF
2549 validate4_3 = x1 == 0xF4 &&
2550 between x2 0x80 0x8F &&
2551 between x3 0x80 0xBF &&
2552 between x4 0x80 0xBF
2554data CodePoint = FreshPoint
2557 | Three !Word8 !Word8
2559 | Four1 !Word8 !Word8
2560 | Four !Word8 !Word8 !Word8
2563{-# INLINE_NORMAL decodeUtf8 #-}
2564decodeUtf8 :: Monad m => Stream m Word8 -> Stream m Char
2565decodeUtf8 (Stream step state) = Stream step' (state, FreshPoint)
2567 {-# INLINE_LATE step' #-}
2568 step' gst (st, FreshPoint) = do
2569 r <- step (adaptState gst) st
2574 Skip (s, YieldPoint $ unsafeChr (fromIntegral c0))
2575 | c0 >= 0xc0 && c0 <= 0xc1 -> error "Invalid Overlong forms"
2576 | c0 >= 0xc2 && c0 <= 0xdf -> Skip (s, Two c0)
2577 | c0 >= 0xe0 && c0 <= 0xef -> Skip (s, GoThree c0)
2578 | c0 >= 0xf0 -> Skip (s, GoFour c0)
2579 | otherwise -> error "Invalid Sequence"
2580 Skip s -> Skip (s, FreshPoint)
2583 -- Decoding of a UTF8 character that spans two bytes with one byte (c0)
2585 step' gst (st, Two c0) = do
2586 r <- step (adaptState gst) st
2590 | c1 < 0x80 || c1 >= 0xc0 -> error "Invalid Sequence"
2591 | otherwise -> Skip (s, YieldPoint $ chr2 c0 c1)
2592 Skip s -> Skip (s, Two c0)
2593 Stop -> error "Input Underflow"
2595 -- Decoding of a UTF8 character that spans three bytes with first byte (c0)
2597 step' gst (st, GoThree c0) = do
2598 r <- step (adaptState gst) st
2602 | not (validate3 c0 c1 0x80) -> error "Invalid Sequence"
2604 | otherwise -> Skip (s, Three c0 c1)
2605 Skip s -> Skip (s, GoThree c0)
2606 Stop -> error "Input Underflow"
2608 -- Two bytes known of a 3 byte UTF8 encoded unicode character.
2609 step' gst (st, Three c0 c1) = do
2610 r <- step (adaptState gst) st
2614 | not (validate3 c0 c1 c2) -> error "Invalid Sequence"
2615 | otherwise -> Skip (s, YieldPoint $ chr3 c0 c1 c2)
2616 Skip s -> Skip (s, Three c0 c1)
2617 Stop -> error "Input Underflow"
2619 -- One byte known of a four byte UTF8 unicode character.
2620 step' gst (st, GoFour c0) = do
2621 r <- step (adaptState gst) st
2625 | not (validate4 c0 c1 0x80 0x80) -> error "Invalid Sequence"
2626 | otherwise -> Skip (s, Four1 c0 c1)
2627 Skip s -> Skip (s, GoFour c0)
2628 Stop -> error "Input Underflow"
2630 -- Two bytes known of a four byte UTF8 unicode character.
2631 step' gst (st, Four1 c0 c1) = do
2632 r <- step (adaptState gst) st
2636 | not (validate4 c0 c1 c2 0x80) -> error "Invalid Sequence"
2637 | otherwise -> Skip (s, Four c0 c1 c2)
2638 Skip s -> Skip (s, Four1 c0 c1)
2639 Stop -> error "Input Underflow"
2641 -- Three bytes known of a three byte UTF8 unicode character.
2642 step' gst (st, Four c0 c1 c2) = do
2643 r <- step (adaptState gst) st
2647 | not (validate4 c0 c1 c2 c3) -> error "Invalid Sequence"
2648 | otherwise -> Skip (s, YieldPoint $ chr4 c0 c1 c2 c3)
2649 Skip s -> Skip (s, Four c0 c1 c2)
2650 Stop -> error "Input Underflow"
2652 -- This way so that we only need one Yield.
2653 step' _ (s, YieldPoint c) = return $ Yield c (s, FreshPoint)
2655data YieldMany x = None
2658{-# INLINE_NORMAL encodeUtf8 #-}
2659encodeUtf8 :: Monad m => Stream m Char -> Stream m Word8
2660encodeUtf8 (Stream step state) = Stream step' (state, None)
2662 {-# INLINE_LATE step' #-}
2663 step' gst (st, None) = do
2664 r <- step (adaptState gst) st
2669 x | x <= 0x7F -> Skip (s, YieldMany [fromIntegral x])
2670 | x <= 0x7FF -> Skip (s, YieldMany (ord2 c))
2673 then error "Encountered a surrogate"
2674 else Skip (s, YieldMany (ord3 c))
2675 | otherwise -> Skip (s, YieldMany (ord4 c))
2676 Skip s -> Skip (s, None)
2678 step' _ (s, YieldMany []) = return $ Skip (s, None)
2679 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