fixed-vector-0.5.0.0: Data/Vector/Fixed/Monomorphic.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
-- |
-- Wrapper function for working with monomorphic vectors. Standard API
-- require vector to be parametric in their element type making it
-- impossible to work with vectors like
--
-- > data Vec3 = Vec3 Double Double Double
--
-- This module provides newtype wrapper which allows use of functions
-- from "Data.Vector.Fixed" with such data types and function which
-- works with such vectors.
--
-- Functions have same meaning as ones from "Data.Vector.Fixed" and
-- documented there.
module Data.Vector.Fixed.Monomorphic (
-- * Vector type class
-- ** Vector size
DimMono
, Z
, S
-- ** Synonyms for small numerals
, F.N1
, F.N2
, F.N3
, F.N4
, F.N5
, F.N6
-- ** Type class
, VectorMono(..)
, Arity
, Fun(..)
, length
-- * Constructors
-- $construction
-- ** Small dimensions
-- $smallDim
, mk1
, mk2
, mk3
, mk4
, mk5
-- ** Functions
, replicate
, replicateM
, generate
, generateM
, unfoldr
, basis
-- * Modifying vectors
-- ** Transformations
, head
, tail
, reverse
, (!)
-- ** Comparison
, eq
-- ** Maps
, map
, mapM
, mapM_
, imap
, imapM
, imapM_
-- * Folding
, foldl
, foldr
, foldl1
, ifoldl
, ifoldr
, fold
, foldMap
, foldM
, ifoldM
-- ** Special folds
, sum
, maximum
, minimum
, and
, or
, all
, any
-- * Zips
, zipWith
, zipWithM
, izipWith
, izipWithM
-- * Conversion
, convert
, toList
, fromList
) where
import Control.Monad (liftM)
import Data.Monoid (Monoid)
import qualified Data.Vector.Fixed as F
import Data.Vector.Fixed.Cont (S,Z,Arity,Fun(..))
import Prelude hiding ( replicate,map,zipWith,maximum,minimum,and,or,all,any
, foldl,foldr,foldl1,length,sum,reverse
, head,tail,mapM,mapM_,sequence,sequence_
)
----------------------------------------------------------------
-- Wrappers for monomorphic vectors
----------------------------------------------------------------
-- | Wrapper for monomorphic vectors it provides 'Vector' instance for
-- monomorphic vectors. Trick is to restrict type parameter @a@ to
-- single possible value.
newtype Mono v a = Mono { getMono :: v }
type instance F.Dim (Mono v) = DimMono v
instance (VectorMono v, a ~ VectorElm v, Arity (DimMono v)) => F.Vector (Mono v) a where
construct = fmap Mono construct
inspect = inspect . getMono
basicIndex = basicIndex . getMono
{-# INLINE construct #-}
{-# INLINE inspect #-}
{-# INLINE basicIndex #-}
-- | Dimensions of monomorphic vector.
type family DimMono v :: *
-- | Counterpart of 'Vector' type class for monomorphic vectors.
class Arity (DimMono v) => VectorMono v where
-- | Type of vector elements.
type VectorElm v :: *
-- | Construct vector
construct :: Fun (DimMono v) (VectorElm v) v
-- | Inspect vector
inspect :: v -> Fun (DimMono v) (VectorElm v) r -> r
-- | Optional more efficient implementation of indexing
basicIndex :: v -> Int -> VectorElm v
basicIndex v i = Mono v F.! i
{-# INLINE basicIndex #-}
-- | Length of vector
length :: Arity (DimMono v) => v -> Int
length = F.length . Mono
{-# INLINE length #-}
----------------------------------------------------------------
--
----------------------------------------------------------------
mk1 :: (VectorMono v, VectorElm v ~ a, DimMono v ~ F.N1)
=> a -> v
mk1 a1 = getMono $ F.mk1 a1
{-# INLINE mk1 #-}
mk2 :: (VectorMono v, VectorElm v ~ a, DimMono v ~ F.N2)
=> a -> a-> v
mk2 a1 a2 = getMono $ F.mk2 a1 a2
{-# INLINE mk2 #-}
mk3 :: (VectorMono v, VectorElm v ~ a, DimMono v ~ F.N3)
=> a -> a-> a -> v
mk3 a1 a2 a3 = getMono $ F.mk3 a1 a2 a3
{-# INLINE mk3 #-}
mk4 :: (VectorMono v, VectorElm v ~ a, DimMono v ~ F.N4)
=> a -> a-> a -> a -> v
mk4 a1 a2 a3 a4 = getMono $ F.mk4 a1 a2 a3 a4
{-# INLINE mk4 #-}
mk5 :: (VectorMono v, VectorElm v ~ a, DimMono v ~ F.N5)
=> a -> a-> a -> a -> a -> v
mk5 a1 a2 a3 a4 a5 = getMono $ F.mk5 a1 a2 a3 a4 a5
{-# INLINE mk5 #-}
replicate :: (VectorMono v, VectorElm v ~ a) => a -> v
{-# INLINE replicate #-}
replicate = getMono . F.replicate
replicateM :: (VectorMono v, VectorElm v ~ a, Monad m) => m a -> m v
{-# INLINE replicateM #-}
replicateM a = getMono `liftM` F.replicateM a
basis :: (VectorMono v, VectorElm v ~ a, Num a) => Int -> v
{-# INLINE basis #-}
basis = getMono . F.basis
unfoldr :: (VectorMono v, VectorElm v ~ a) => (b -> (a,b)) -> b -> v
{-# INLINE unfoldr #-}
unfoldr f = getMono . F.unfoldr f
generate :: (VectorMono v, VectorElm v ~ a) => (Int -> a) -> v
{-# INLINE generate #-}
generate = getMono . F.generate
generateM :: (Monad m, VectorMono v, VectorElm v ~ a) => (Int -> m a) -> m v
{-# INLINE generateM #-}
generateM f = getMono `liftM` F.generateM f
----------------------------------------------------------------
head :: (VectorMono v, VectorElm v ~ a, DimMono v ~ S n) => v -> a
{-# INLINE head #-}
head = F.head . Mono
tail :: ( VectorMono v, VectorElm v ~ a
, VectorMono w, VectorElm w ~ a
, DimMono v ~ S (DimMono w))
=> v -> w
{-# INLINE tail #-}
tail v = getMono $ F.tail $ Mono v
reverse :: (VectorMono v) => v -> v
reverse = getMono . F.reverse . Mono
{-# INLINE reverse #-}
(!) :: (VectorMono v, VectorElm v ~ a) => v -> Int -> a
{-# INLINE (!) #-}
v ! n = Mono v F.! n
foldl :: (VectorMono v, VectorElm v ~ a)
=> (b -> a -> b) -> b -> v -> b
{-# INLINE foldl #-}
foldl f x = F.foldl f x . Mono
foldr :: (VectorMono v, VectorElm v ~ a)
=> (a -> b -> b) -> b -> v -> b
{-# INLINE foldr #-}
foldr f x = F.foldr f x . Mono
foldl1 :: (VectorMono v, VectorElm v ~ a, DimMono v ~ S n)
=> (a -> a -> a) -> v -> a
{-# INLINE foldl1 #-}
foldl1 f = F.foldl1 f . Mono
ifoldr :: (VectorMono v, VectorElm v ~ a)
=> (Int -> a -> b -> b) -> b -> v -> b
{-# INLINE ifoldr #-}
ifoldr f x = F.ifoldr f x . Mono
ifoldl :: (VectorMono v, VectorElm v ~ a)
=> (b -> Int -> a -> b) -> b -> v -> b
{-# INLINE ifoldl #-}
ifoldl f z = F.ifoldl f z . Mono
fold :: (VectorMono v, Monoid (VectorElm v)) => v -> VectorElm v
fold = F.fold . Mono
{-# INLINE fold #-}
foldMap :: (VectorMono v, Monoid m) => (VectorElm v -> m) -> v -> m
foldMap f = F.foldMap f . Mono
{-# INLINE foldMap #-}
foldM :: (VectorMono v, VectorElm v ~ a, Monad m)
=> (b -> a -> m b) -> b -> v -> m b
{-# INLINE foldM #-}
foldM f x = F.foldM f x . Mono
ifoldM :: (VectorMono v, VectorElm v ~ a, Monad m) => (b -> Int -> a -> m b) -> b -> v -> m b
{-# INLINE ifoldM #-}
ifoldM f x = F.ifoldM f x . Mono
----------------------------------------------------------------
sum :: (VectorMono v, VectorElm v ~ a, Num a) => v -> a
sum = F.sum . Mono
{-# INLINE sum #-}
maximum :: (VectorMono v, VectorElm v ~ a, DimMono v ~ S n, Ord a) => v -> a
maximum = F.maximum . Mono
{-# INLINE maximum #-}
minimum :: (VectorMono v, VectorElm v ~ a, DimMono v ~ S n, Ord a) => v -> a
minimum = F.minimum . Mono
{-# INLINE minimum #-}
and :: (VectorMono v, VectorElm v ~ Bool) => v -> Bool
and = F.and . Mono
{-# INLINE and #-}
or :: (VectorMono v, VectorElm v ~ Bool) => v -> Bool
or = F.or . Mono
{-# INLINE or #-}
all :: (VectorMono v, VectorElm v ~ a) => (a -> Bool) -> v -> Bool
all f = F.all f . Mono
{-# INLINE all #-}
any :: (VectorMono v, VectorElm v ~ a) => (a -> Bool) -> v -> Bool
any f = F.any f . Mono
{-# INLINE any #-}
----------------------------------------------------------------
eq :: (VectorMono v, VectorElm v ~ a, Eq a) => v -> v -> Bool
{-# INLINE eq #-}
eq v w = F.eq (Mono v) (Mono w)
----------------------------------------------------------------
map :: (VectorMono v, VectorElm v ~ a) => (a -> a) -> v -> v
{-# INLINE map #-}
map f = getMono . F.map f . Mono
mapM :: (VectorMono v, VectorElm v ~ a, Monad m)
=> (a -> m a) -> v -> m v
{-# INLINE mapM #-}
mapM f v = getMono `liftM` F.mapM f (Mono v)
mapM_ :: (VectorMono v, VectorElm v ~ a, Monad m) => (a -> m b) -> v -> m ()
{-# INLINE mapM_ #-}
mapM_ f = F.mapM_ f . Mono
imap :: (VectorMono v, VectorElm v ~ a) =>
(Int -> a -> a) -> v -> v
{-# INLINE imap #-}
imap f = getMono . F.imap f . Mono
imapM :: (VectorMono v, VectorElm v ~ a, Monad m)
=> (Int -> a -> m a) -> v -> m v
{-# INLINE imapM #-}
imapM f v = getMono `liftM` F.imapM f (Mono v)
imapM_ :: (VectorMono v, VectorElm v ~ a, Monad m) => (Int -> a -> m b) -> v -> m ()
{-# INLINE imapM_ #-}
imapM_ f = F.imapM_ f . Mono
----------------------------------------------------------------
zipWith :: (VectorMono v, VectorElm v ~ a)
=> (a -> a -> a) -> v -> v -> v
{-# INLINE zipWith #-}
zipWith f v u = getMono $ F.zipWith f (Mono v) (Mono u)
zipWithM :: (VectorMono v, VectorElm v ~ a, Monad m)
=> (a -> a -> m a) -> v -> v -> m v
{-# INLINE zipWithM #-}
zipWithM f v u = getMono `liftM` F.zipWithM f (Mono v) (Mono u)
izipWith :: (VectorMono v, VectorElm v ~ a)
=> (Int -> a -> a -> a) -> v -> v -> v
{-# INLINE izipWith #-}
izipWith f v u = getMono $ F.izipWith f (Mono v) (Mono u)
izipWithM :: (VectorMono v, VectorElm v ~ a, Monad m)
=> (Int -> a -> a -> m a) -> v -> v -> m v
{-# INLINE izipWithM #-}
izipWithM f v u = getMono `liftM` F.izipWithM f (Mono v) (Mono u)
----------------------------------------------------------------
convert :: (VectorMono v, VectorMono w, VectorElm v ~ VectorElm w, DimMono v ~ DimMono w)
=> v -> w
{-# INLINE convert #-}
convert = getMono . F.convert . Mono
toList :: (VectorMono v, VectorElm v ~ a) => v -> [a]
toList = foldr (:) []
fromList :: (VectorMono v, VectorElm v ~ a) => [a] -> v
{-# INLINE fromList #-}
fromList = getMono . F.fromList