on c175cdd help sign in
streamly/src/Streamly/Streams/StreamDType.hs
100 lines 3.1 kB history raw
1{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE CPP #-}
3{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE ExistentialQuantification #-}
5{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE PatternSynonyms #-}
9{-# LANGUAGE ViewPatterns #-}
10{-# LANGUAGE RankNTypes #-}
12#include "inline.hs"
14-- |
15-- Module : Streamly.Streams.StreamDType
16-- Copyright : (c) 2018 Harendra Kumar
17--
18-- License : BSD3
19-- Maintainer : harendra.kumar@gmail.com
20-- Stability : experimental
21-- Portability : GHC
23module Streamly.Streams.StreamDType
24 (
25 -- * The stream type
26 Step (..)
27 -- XXX UnStream is exported to avoid a performance issue in concatMap if we
28 -- use the pattern synonym "Stream".
29#if __GLASGOW_HASKELL__ >= 800
30 , Stream (Stream, UnStream)
31#else
32 , Stream (UnStream)
33 , pattern Stream
34#endif
35 , map
36 , mapM
37 )
38where
40import Streamly.SVar (State(..), adaptState)
41import qualified Streamly.Streams.StreamK as K
42import Prelude hiding (map, mapM)
44------------------------------------------------------------------------------
45-- The direct style stream type
46------------------------------------------------------------------------------
48-- | A stream is a succession of 'Step's. A 'Yield' produces a single value and
49-- the next state of the stream. 'Stop' indicates there are no more values in
50-- the stream.
51data Step s a = Yield a s | Skip s | Stop
53instance Functor (Step s) where
54 {-# INLINE fmap #-}
55 fmap f (Yield x s) = Yield (f x) s
56 fmap _ (Skip s) = Skip s
57 fmap _ Stop = Stop
59-- gst = global state
60-- | A stream consists of a step function that generates the next step given a
61-- current state, and the current state.
62data Stream m a =
63 forall s. UnStream (State K.Stream m a -> s -> m (Step s a)) s
65unShare :: Stream m a -> Stream m a
66unShare (UnStream step state) = UnStream step' state
67 where step' gst = step (adaptState gst)
69pattern Stream :: (State K.Stream m a -> s -> m (Step s a)) -> s -> Stream m a
70pattern Stream step state <- (unShare -> UnStream step state)
71 where Stream = UnStream
73#if __GLASGOW_HASKELL__ >= 802
74{-# COMPLETE Stream #-}
75#endif
77------------------------------------------------------------------------------
78-- Instances
79------------------------------------------------------------------------------
81-- | Map a monadic function over a 'Stream'
82{-# INLINE_NORMAL mapM #-}
83mapM :: Monad m => (a -> m b) -> Stream m a -> Stream m b
84mapM f (Stream step state) = Stream step' state
85 where
86 {-# INLINE_LATE step' #-}
87 step' gst st = do
88 r <- step (adaptState gst) st
89 case r of
90 Yield x s -> f x >>= \a -> return $ Yield a s
91 Skip s -> return $ Skip s
92 Stop -> return Stop
94{-# INLINE map #-}
95map :: Monad m => (a -> b) -> Stream m a -> Stream m b
96map f = mapM (return . f)
98instance Monad m => Functor (Stream m) where
99 {-# INLINE fmap #-}
100 fmap = map