synthesizer-core-0.9.0.1: src/Synthesizer/ChunkySize.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Synthesizer.ChunkySize where
import qualified Synthesizer.Generic.Cut as Cut
import qualified Number.NonNegativeChunky as Chunky
import qualified Numeric.NonNegative.Chunky as Chunky98
import qualified Algebra.ToInteger as ToInteger
import qualified Algebra.ToRational as ToRational
import qualified Algebra.Absolute as Absolute
import qualified Algebra.RealIntegral as RealIntegral
import qualified Algebra.IntegralDomain as Integral
import qualified Algebra.NonNegative as NonNeg
import qualified Algebra.ZeroTestable as ZeroTestable
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import qualified Algebra.Monoid as Monoid
import Algebra.Ring ((*), )
import Algebra.Additive ((+), (-), )
import qualified Data.StorableVector.Lazy as SigSt
import qualified Data.StorableVector.Lazy.Pattern as SigStV
import qualified Data.List as List
import Data.Monoid (Monoid, mempty, )
import Data.Semigroup (Semigroup, (<>), )
import qualified Test.QuickCheck as QC
import qualified Prelude as P
import Prelude (Eq, Ord, Show, Int, fmap, max, min, id, (.), ($), (==), )
{- |
This type is used for specification of the maximum size of strict packets.
Packets can be smaller, can have different sizes in one signal.
In some kinds of streams, like lists and stateful generators,
the packet size is always 1.
The packet size is not just a burden caused by efficiency,
but we need control over packet size in applications with feedback.
ToDo: Make the element type of the corresponding signal a type parameter.
This helps to distinguish chunk sizes of scalar and vectorised signals.
-}
newtype LazySize = LazySize Int
deriving (Eq, Ord, Show,
Additive.C, Ring.C, ZeroTestable.C,
ToInteger.C, ToRational.C, Absolute.C,
RealIntegral.C, Integral.C)
instance Semigroup LazySize where
LazySize a <> LazySize b = LazySize (a + b)
instance Monoid LazySize where
mempty = LazySize 0
instance Monoid.C LazySize where
idt = LazySize 0
LazySize a <*> LazySize b = LazySize (a + b)
instance NonNeg.C LazySize where
split = NonNeg.splitDefault (\(LazySize n) -> n) LazySize
instance QC.Arbitrary LazySize where
arbitrary =
case SigSt.defaultChunkSize of
SigSt.ChunkSize n -> fmap LazySize (QC.choose (1, 2 * n))
instance Cut.Consume LazySize where
null (LazySize n) = n==0
length (LazySize n) = n
instance Cut.Transform LazySize where
{-# INLINE take #-}
take m (LazySize n) = LazySize $ min (max 0 m) n
{-# INLINE drop #-}
drop m (LazySize n) = LazySize $ max 0 $ n - max 0 m
{-# INLINE splitAt #-}
splitAt m x =
let y = Cut.take m x
in (y, x-y)
{-# INLINE dropMarginRem #-}
dropMarginRem n m x@(LazySize xs) =
let d = min m $ max 0 $ xs - n
in (m-d, Cut.drop d x)
{-# INLINE reverse #-}
reverse = id
type T = Chunky.T LazySize
fromStorableVectorSize ::
SigStV.LazySize -> T
fromStorableVectorSize =
Chunky.fromChunks .
List.map (\(SigSt.ChunkSize size) -> (LazySize size)) .
Chunky98.toChunks
toStorableVectorSize ::
T -> SigStV.LazySize
toStorableVectorSize =
Chunky98.fromChunks .
List.map (\(LazySize size) -> (SigSt.ChunkSize size)) .
Chunky.toChunks
toNullList :: T -> [()]
toNullList =
List.concatMap (\(LazySize n) -> List.replicate n ()) .
Chunky.toChunks