{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE ScopedTypeVariables #-}
module System.FS.Sim.Stream (
Stream (..)
, InternalInfo (..)
, runStream
, runStreamN
, runStreamIndefinitely
, always
, empty
, repeating
, unsafeMkInfinite
, unsafeMkFinite
, filter
, null
, isFinite
, isInfinite
, genFinite
, genFiniteN
, genInfinite
, genMaybe
, shrinkStream
, liftShrinkStream
) where
import Control.Monad (replicateM)
import Prelude hiding (filter, isInfinite, null)
import qualified Prelude
import qualified Test.QuickCheck as QC
import Test.QuickCheck (Gen)
data Stream a =
UnsafeStream {
forall a. Stream a -> InternalInfo
unsafeStreamInternalInfo :: InternalInfo
, forall a. Stream a -> [Maybe a]
unsafeStreamList :: [Maybe a]
}
deriving (forall a b. (a -> b) -> Stream a -> Stream b)
-> (forall a b. a -> Stream b -> Stream a) -> Functor Stream
forall a b. a -> Stream b -> Stream a
forall a b. (a -> b) -> Stream a -> Stream b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Stream a -> Stream b
fmap :: forall a b. (a -> b) -> Stream a -> Stream b
$c<$ :: forall a b. a -> Stream b -> Stream a
<$ :: forall a b. a -> Stream b -> Stream a
Functor
data InternalInfo = Infinite | Finite
instance Show a => Show (Stream a) where
showsPrec :: Int -> Stream a -> ShowS
showsPrec Int
n (UnsafeStream InternalInfo
info [Maybe a]
xs) = case InternalInfo
info of
InternalInfo
Infinite -> (String
"<infinite stream>" String -> ShowS
forall a. [a] -> [a] -> [a]
++)
InternalInfo
Finite -> (if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10 then (Char
'('Char -> ShowS
forall a. a -> [a] -> [a]
:) else ShowS
forall a. a -> a
id)
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe a] -> ShowS
forall a. Show a => a -> ShowS
shows [Maybe a]
xs
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
" ++ ..." String -> ShowS
forall a. [a] -> [a] -> [a]
++)
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10 then (Char
')'Char -> ShowS
forall a. a -> [a] -> [a]
:) else ShowS
forall a. a -> a
id)
runStream :: Stream a -> (Maybe a, Stream a)
runStream :: forall a. Stream a -> (Maybe a, Stream a)
runStream s :: Stream a
s@(UnsafeStream InternalInfo
_ [] ) = (Maybe a
forall a. Maybe a
Nothing, Stream a
s)
runStream (UnsafeStream InternalInfo
info (Maybe a
a:[Maybe a]
as)) = (Maybe a
a, InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
info [Maybe a]
as)
runStreamN :: Int -> Stream a -> ([Maybe a], Stream a)
runStreamN :: forall a. Int -> Stream a -> ([Maybe a], Stream a)
runStreamN Int
n Stream a
s
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = ([], Stream a
s)
| Bool
otherwise =
let (Maybe a
x, Stream a
s') = Stream a -> (Maybe a, Stream a)
forall a. Stream a -> (Maybe a, Stream a)
runStream Stream a
s
([Maybe a]
xs, Stream a
s'') = Int -> Stream a -> ([Maybe a], Stream a)
forall a. Int -> Stream a -> ([Maybe a], Stream a)
runStreamN (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Stream a
s'
in (Maybe a
xMaybe a -> [Maybe a] -> [Maybe a]
forall a. a -> [a] -> [a]
:[Maybe a]
xs, Stream a
s'')
runStreamIndefinitely :: Stream a -> [Maybe a]
runStreamIndefinitely :: forall a. Stream a -> [Maybe a]
runStreamIndefinitely (UnsafeStream InternalInfo
_ [Maybe a]
as) = [Maybe a]
as [Maybe a] -> [Maybe a] -> [Maybe a]
forall a. [a] -> [a] -> [a]
++ Maybe a -> [Maybe a]
forall a. a -> [a]
repeat Maybe a
forall a. Maybe a
Nothing
empty :: Stream a
empty :: forall a. Stream a
empty = InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Finite []
always :: a -> Stream a
always :: forall a. a -> Stream a
always a
x = InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Infinite (Maybe a -> [Maybe a]
forall a. a -> [a]
repeat (a -> Maybe a
forall a. a -> Maybe a
Just a
x))
repeating :: [Maybe a] -> Stream a
repeating :: forall a. [Maybe a] -> Stream a
repeating [Maybe a]
xs = InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Infinite ([Maybe a] -> Stream a) -> [Maybe a] -> Stream a
forall a b. (a -> b) -> a -> b
$ [Maybe a] -> [Maybe a]
forall a. HasCallStack => [a] -> [a]
cycle [Maybe a]
xs
unsafeMkFinite :: [Maybe a] -> Stream a
unsafeMkFinite :: forall a. [Maybe a] -> Stream a
unsafeMkFinite = InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Finite
unsafeMkInfinite :: [Maybe a] -> Stream a
unsafeMkInfinite :: forall a. [Maybe a] -> Stream a
unsafeMkInfinite = InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Infinite
filter :: (Maybe a -> Bool) -> Stream a -> Stream a
filter :: forall a. (Maybe a -> Bool) -> Stream a -> Stream a
filter Maybe a -> Bool
p (UnsafeStream InternalInfo
info [Maybe a]
xs) = InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
info ((Maybe a -> Bool) -> [Maybe a] -> [Maybe a]
forall a. (a -> Bool) -> [a] -> [a]
Prelude.filter Maybe a -> Bool
p [Maybe a]
xs)
null :: Stream a -> Bool
null :: forall a. Stream a -> Bool
null (UnsafeStream InternalInfo
Finite []) = Bool
True
null Stream a
_ = Bool
False
isFinite :: Stream a -> Bool
isFinite :: forall a. Stream a -> Bool
isFinite (UnsafeStream InternalInfo
Finite [Maybe a]
_) = Bool
True
isFinite (UnsafeStream InternalInfo
Infinite [Maybe a]
_) = Bool
False
isInfinite :: Stream a -> Bool
isInfinite :: forall a. Stream a -> Bool
isInfinite (UnsafeStream InternalInfo
Finite [Maybe a]
_) = Bool
False
isInfinite (UnsafeStream InternalInfo
Infinite [Maybe a]
_) = Bool
True
shrinkStream :: Stream a -> [Stream a]
shrinkStream :: forall a. Stream a -> [Stream a]
shrinkStream (UnsafeStream InternalInfo
info [Maybe a]
xs0) = case InternalInfo
info of
InternalInfo
Infinite -> InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Finite ([Maybe a] -> Stream a) -> [[Maybe a]] -> [Stream a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int -> [Maybe a] -> [Maybe a]
forall a. Int -> [a] -> [a]
take Int
n [Maybe a]
xs0 | Int
n <- (Int -> Int) -> [Int] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int
2Int -> Int -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^) [Int
0 :: Int ..]]
InternalInfo
Finite -> InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Finite ([Maybe a] -> Stream a) -> [[Maybe a]] -> [Stream a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Maybe a -> [Maybe a]) -> [Maybe a] -> [[Maybe a]]
forall a. (a -> [a]) -> [a] -> [[a]]
QC.shrinkList ([Maybe a] -> Maybe a -> [Maybe a]
forall a b. a -> b -> a
const []) [Maybe a]
xs0
liftShrinkStream :: (Maybe a -> [Maybe a]) -> Stream a -> [Stream a]
liftShrinkStream :: forall a. (Maybe a -> [Maybe a]) -> Stream a -> [Stream a]
liftShrinkStream Maybe a -> [Maybe a]
shrinkOne (UnsafeStream InternalInfo
info [Maybe a]
xs0) = case InternalInfo
info of
InternalInfo
Infinite -> InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Finite ([Maybe a] -> Stream a) -> [[Maybe a]] -> [Stream a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int -> [Maybe a] -> [Maybe a]
forall a. Int -> [a] -> [a]
take Int
n [Maybe a]
xs0 | Int
n <- (Int -> Int) -> [Int] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int
2Int -> Int -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^) [Int
0 :: Int ..]]
InternalInfo
Finite -> InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Finite ([Maybe a] -> Stream a) -> [[Maybe a]] -> [Stream a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Maybe a -> [Maybe a]) -> [Maybe a] -> [[Maybe a]]
forall a. (a -> [a]) -> [a] -> [[a]]
QC.shrinkList Maybe a -> [Maybe a]
shrinkOne [Maybe a]
xs0
genMaybe ::
Int
-> Int
-> Gen a
-> Gen (Maybe a)
genMaybe :: forall a. Int -> Int -> Gen a -> Gen (Maybe a)
genMaybe Int
nLi Int
jLi Gen a
genA = [(Int, Gen (Maybe a))] -> Gen (Maybe a)
forall a. HasCallStack => [(Int, Gen a)] -> Gen a
QC.frequency
[ (Int
nLi, Maybe a -> Gen (Maybe a)
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing)
, (Int
jLi, a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> Gen a -> Gen (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
genA)
]
genFiniteN ::
Int
-> Gen (Maybe a)
-> Gen (Stream a)
genFiniteN :: forall a. Int -> Gen (Maybe a) -> Gen (Stream a)
genFiniteN Int
n Gen (Maybe a)
gen = InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Finite ([Maybe a] -> Stream a) -> Gen [Maybe a] -> Gen (Stream a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen (Maybe a) -> Gen [Maybe a]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n Gen (Maybe a)
gen
genFinite ::
Gen (Maybe a)
-> Gen (Stream a)
genFinite :: forall a. Gen (Maybe a) -> Gen (Stream a)
genFinite Gen (Maybe a)
gen = InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Finite ([Maybe a] -> Stream a) -> Gen [Maybe a] -> Gen (Stream a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Maybe a) -> Gen [Maybe a]
forall a. Gen a -> Gen [a]
QC.listOf Gen (Maybe a)
gen
genInfinite ::
Gen (Maybe a)
-> Gen (Stream a)
genInfinite :: forall a. Gen (Maybe a) -> Gen (Stream a)
genInfinite Gen (Maybe a)
gen = InternalInfo -> [Maybe a] -> Stream a
forall a. InternalInfo -> [Maybe a] -> Stream a
UnsafeStream InternalInfo
Infinite ([Maybe a] -> Stream a) -> Gen [Maybe a] -> Gen (Stream a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Maybe a) -> Gen [Maybe a]
forall a. Gen a -> Gen [a]
QC.infiniteListOf Gen (Maybe a)
gen