#include "fusion-phases.h"
module Data.Array.Parallel.Stream.Flat.Basics (
emptyS, singletonS, consS, replicateS, replicateEachS, (+++), indexedS,
tailS,
toStream, fromStream
) where
import Data.Array.Parallel.Base (
(:*:)(..), MaybeS(..), EitherS(..), Box(..))
import Data.Array.Parallel.Stream.Flat.Stream
emptyS :: Stream a
emptyS = Stream (const Done) () 0
singletonS :: a -> Stream a
singletonS x = Stream next True 1
where
next True = Yield x False
next False = Done
consS :: a -> Stream a -> Stream a
consS x (Stream next s n) = Stream next' (JustS (Box x) :*: s) (n+1)
where
next' (JustS (Box x) :*: s) = Yield x (NothingS :*: s)
next' (NothingS :*: s) = case next s of
Yield y s' -> Yield y (NothingS :*: s')
Skip s' -> Skip (NothingS :*: s')
Done -> Done
replicateS :: Int -> a -> Stream a
replicateS n x = Stream next 0 n
where
next i | i == n = Done
| otherwise = Yield x (i+1)
replicateEachS :: Int -> Stream (Int :*: a) -> Stream a
replicateEachS n (Stream next s _) =
Stream next' (0 :*: NothingS :*: s) n
where
next' (0 :*: _ :*: s) =
case next s of
Done -> Done
Skip s' -> Skip (0 :*: NothingS :*: s')
Yield (k :*: x) s' -> Skip (k :*: JustS (Box x) :*: s')
next' (k :*: NothingS :*: s) = Done
next' (k :*: JustS (Box x) :*: s) =
Yield x (k1 :*: JustS (Box x) :*: s)
(+++) :: Stream a -> Stream a -> Stream a
Stream next1 s1 n1 +++ Stream next2 s2 n2 = Stream next (LeftS s1) (n1 + n2)
where
next (LeftS s1) =
case next1 s1 of
Done -> Skip (RightS s2)
Skip s1' -> Skip (LeftS s1')
Yield x s1' -> Yield x (LeftS s1')
next (RightS s2) =
case next2 s2 of
Done -> Done
Skip s2' -> Skip (RightS s2')
Yield x s2' -> Yield x (RightS s2')
indexedS :: Stream a -> Stream (Int :*: a)
indexedS (Stream next s n) = Stream next' (0 :*: s) n
where
next' (i :*: s) = case next s of
Yield x s' -> Yield (i :*: x) ((i+1) :*: s')
Skip s' -> Skip (i :*: s')
Done -> Done
tailS :: Stream a -> Stream a
tailS (Stream next s n) = Stream next' (False :*: s) (n1)
where
next' (False :*: s) = case next s of
Yield x s' -> Skip (True :*: s')
Skip s' -> Skip (False :*: s')
Done -> error "Stream.tailS: empty stream"
next' (True :*: s) = case next s of
Yield x s' -> Yield x (True :*: s')
Skip s' -> Skip (True :*: s')
Done -> Done
toStream :: [a] -> Stream a
toStream xs = Stream gen (Box xs) (length xs)
where
gen (Box []) = Done
gen (Box (x:xs)) = Yield x (Box xs)
fromStream :: Stream a -> [a]
fromStream (Stream next s _) = gen s
where
gen s = case next s of
Done -> []
Skip s' -> gen s'
Yield x s' -> x : gen s'