on 0258d77 help sign in
streamly/src/Streamly/Streams/StreamDType.hs
98 lines 2.9 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#if __GLASGOW_HASKELL__ >= 800
28 , Stream (Stream)
29#else
30 , Stream ()
31 , pattern Stream
32#endif
33 , map
34 , mapM
35 )
36where
38import Streamly.SVar (State(..), adaptState)
39import qualified Streamly.Streams.StreamK as K
40import Prelude hiding (map, mapM)
42------------------------------------------------------------------------------
43-- The direct style stream type
44------------------------------------------------------------------------------
46-- | A stream is a succession of 'Step's. A 'Yield' produces a single value and
47-- the next state of the stream. 'Stop' indicates there are no more values in
48-- the stream.
49data Step s a = Yield a s | Skip s | Stop
51instance Functor (Step s) where
52 {-# INLINE fmap #-}
53 fmap f (Yield x s) = Yield (f x) s
54 fmap _ (Skip s) = Skip s
55 fmap _ Stop = Stop
57-- gst = global state
58-- | A stream consists of a step function that generates the next step given a
59-- current state, and the current state.
60data Stream m a =
61 forall s. UnStream (State K.Stream m a -> s -> m (Step s a)) s
63unShare :: Stream m a -> Stream m a
64unShare (UnStream step state) = UnStream step' state
65 where step' gst = step (adaptState gst)
67pattern Stream :: (State K.Stream m a -> s -> m (Step s a)) -> s -> Stream m a
68pattern Stream step state <- (unShare -> UnStream step state)
69 where Stream = UnStream
71#if __GLASGOW_HASKELL__ >= 802
72{-# COMPLETE Stream #-}
73#endif
75------------------------------------------------------------------------------
76-- Instances
77------------------------------------------------------------------------------
79-- | Map a monadic function over a 'Stream'
80{-# INLINE_NORMAL mapM #-}
81mapM :: Monad m => (a -> m b) -> Stream m a -> Stream m b
82mapM f (Stream step state) = Stream step' state
83 where
84 {-# INLINE_LATE step' #-}
85 step' gst st = do
86 r <- step (adaptState gst) st
87 case r of
88 Yield x s -> f x >>= \a -> return $ Yield a s
89 Skip s -> return $ Skip s
90 Stop -> return Stop
92{-# INLINE map #-}
93map :: Monad m => (a -> b) -> Stream m a -> Stream m b
94map f = mapM (return . f)
96instance Monad m => Functor (Stream m) where
97 {-# INLINE fmap #-}
98 fmap = map