module Crypto.Lol.Types.IZipVector
( IZipVector, iZipVector, unIZipVector
) where
import Crypto.Lol.Factored
import Algebra.ZeroTestable as ZeroTestable
import Control.DeepSeq
import Data.Data
import Data.Functor.Trans.Tagged
import Data.Vector as V
newtype IZipVector (m :: Factored) a =
IZipVector {
unIZipVector :: Vector a}
deriving (Show, Eq, Data, NFData, Typeable, Functor,
Foldable, Traversable, ZeroTestable.C)
type role IZipVector representational representational
iZipVector :: forall m a . (Fact m) => Vector a -> Maybe (IZipVector m a)
iZipVector = let n = proxy totientFact (Proxy::Proxy m)
in \vec -> if n == V.length vec
then Just $ IZipVector vec
else Nothing
repl :: forall m a . (Fact m) => a -> IZipVector m a
repl = let n = proxy totientFact (Proxy::Proxy m)
in IZipVector . V.replicate n
instance (Fact m) => Applicative (IZipVector m) where
pure = repl
(IZipVector f) <*> (IZipVector a) = IZipVector $ V.zipWith ($) f a
instance (ZeroTestable.C a) => ZeroTestable.C (Vector a) where
isZero = V.all isZero