module Synthesizer.Zip where
import qualified Synthesizer.Generic.Cut as CutG
import Data.Monoid (Monoid, mempty, mappend, )
{- |
Parallel combination of two signals of equal length.
-}
data T a b = Cons a b
instance (Monoid a, Monoid b) => Monoid (T a b) where
mempty = Cons mempty mempty
mappend (Cons a0 b0) (Cons a1 b1) =
Cons (mappend a0 a1) (mappend b0 b1)
instance (CutG.Read a, CutG.Read b) => CutG.Read (T a b) where
{-# INLINE null #-}
null (Cons a b) =
case (CutG.null a, CutG.null b) of
(False, False) -> False
(True, True) -> True
_ -> error "Zipped signals: one is empty and the other one is not"
{-# INLINE length #-}
length (Cons a b) =
let lenA = CutG.length a
lenB = CutG.length b
in if lenA == lenB
then lenA
else error "Zipped signals: the lengths differ"
{-
Parallel combination of two signals
where the combined signal has the length of the shorter member.
This is like in zipWith.
instance (CutG.Read a, CutG.Read b) => CutG.Read (Parallel a b) where
null (Parallel a b) = CutG.null a || CutG.null b
length (Parallel a b) = min (CutG.length a) (CutG.length b)
-}
instance (CutG.NormalForm a, CutG.NormalForm b) => CutG.NormalForm (T a b) where
{-# INLINE evaluateHead #-}
evaluateHead (Cons a b) =
case (CutG.evaluateHead a, CutG.evaluateHead b) of
((), ()) -> ()
instance (CutG.Transform a, CutG.Transform b) => CutG.Transform (T a b) where
{-# INLINE take #-}
take n (Cons a b) =
Cons (CutG.take n a) (CutG.take n b)
{-# INLINE drop #-}
drop n (Cons a b) =
Cons (CutG.drop n a) (CutG.drop n b)
{-# INLINE splitAt #-}
splitAt n (Cons a b) =
let (a0,a1) = CutG.splitAt n a
(b0,b1) = CutG.splitAt n b
in (Cons a0 b0, Cons a1 b1)
{-# INLINE dropMarginRem #-}
dropMarginRem n m (Cons a0 b0) =
let (ka,a1) = CutG.dropMarginRem n m a0
(kb,b1) = CutG.dropMarginRem n m b0
in if ka==kb
then (ka, Cons a1 b1)
else error "Zip.dropMarginRem: margins differ"
{-# INLINE reverse #-}
reverse (Cons a b) =
Cons (CutG.reverse a) (CutG.reverse b)