From 5a59b4f5d424e91e81441f8f330832be3cd3a38a Mon Sep 17 00:00:00 2001 From: Alexey Khudyakov Date: Tue, 20 Jan 2026 23:00:27 +0300 Subject: [PATCH 1/7] Fix -Wtype-equality-out-of-scope --- fixed-vector/Data/Vector/Fixed.hs | 2 +- fixed-vector/Data/Vector/Fixed/Boxed.hs | 2 +- fixed-vector/Data/Vector/Fixed/Cont.hs | 1 + fixed-vector/Data/Vector/Fixed/Strict.hs | 2 +- fixed-vector/Data/Vector/Fixed/Unboxed.hs | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fixed-vector/Data/Vector/Fixed.hs b/fixed-vector/Data/Vector/Fixed.hs index aa8009a..83e3ed3 100644 --- a/fixed-vector/Data/Vector/Fixed.hs +++ b/fixed-vector/Data/Vector/Fixed.hs @@ -211,7 +211,7 @@ import Data.Vector.Fixed.Cont (Vector(..),Dim,length,ContVec,PeanoNum(..), import Data.Vector.Fixed.Cont qualified as C import Data.Vector.Fixed.Internal as I -import Prelude (Show(..),Eq(..),Ord(..),Num(..),Functor(..),id,(.),($),(<$>),undefined,flip) +import Prelude (Show(..),Eq(..),Ord(..),Num(..),Functor(..),id,(.),($),(<$>),undefined,flip,type(~)) -- $construction diff --git a/fixed-vector/Data/Vector/Fixed/Boxed.hs b/fixed-vector/Data/Vector/Fixed/Boxed.hs index adca4e5..0a6b3fb 100644 --- a/fixed-vector/Data/Vector/Fixed/Boxed.hs +++ b/fixed-vector/Data/Vector/Fixed/Boxed.hs @@ -30,7 +30,7 @@ import Foreign.Storable (Storable) import GHC.TypeLits import GHC.Exts (proxy#) import Prelude ( Show(..),Eq(..),Ord(..),Functor(..),Monad(..) - , ($!),error,(<$>)) + , ($!),error,(<$>),type(~)) import Data.Vector.Fixed hiding (index) import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index) diff --git a/fixed-vector/Data/Vector/Fixed/Cont.hs b/fixed-vector/Data/Vector/Fixed/Cont.hs index 8112647..02e6ca7 100644 --- a/fixed-vector/Data/Vector/Fixed/Cont.hs +++ b/fixed-vector/Data/Vector/Fixed/Cont.hs @@ -136,6 +136,7 @@ import Prelude ( Bool(..), Int, Maybe(..), Either(..) , Eq(..), Ord(..), Num(..), Functor(..), Applicative(..), Monad(..) , Semigroup(..), Monoid(..) , (.), ($), (&&), (||), (<$>), id, error, otherwise, fst + , type(~) ) diff --git a/fixed-vector/Data/Vector/Fixed/Strict.hs b/fixed-vector/Data/Vector/Fixed/Strict.hs index fbc7fb0..b0818bc 100644 --- a/fixed-vector/Data/Vector/Fixed/Strict.hs +++ b/fixed-vector/Data/Vector/Fixed/Strict.hs @@ -20,7 +20,7 @@ import Foreign.Storable (Storable) import GHC.TypeLits import GHC.Exts (proxy#) import Prelude ( Show(..),Eq(..),Ord(..),Functor(..),Monad(..) - , ($!),error,(<$>)) + , ($!),error,(<$>),type (~)) import Data.Vector.Fixed hiding (index) import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index) diff --git a/fixed-vector/Data/Vector/Fixed/Unboxed.hs b/fixed-vector/Data/Vector/Fixed/Unboxed.hs index b332797..ee99988 100644 --- a/fixed-vector/Data/Vector/Fixed/Unboxed.hs +++ b/fixed-vector/Data/Vector/Fixed/Unboxed.hs @@ -43,7 +43,7 @@ import Foreign.Storable (Storable) import GHC.TypeLits import GHC.Exts (Proxy#, proxy#) import Prelude ( Show(..),Eq(..),Ord(..),Num(..),Applicative(..) - , Int,Double,Float,Char,Bool(..),($),id) + , Int,Double,Float,Char,Bool(..),($),id,type (~)) import Data.Vector.Fixed (Dim,Vector(..),ViaFixed(..)) import Data.Vector.Fixed qualified as F From 673b5cc9589c265b2f85067208899c75faaae282 Mon Sep 17 00:00:00 2001 From: Alexey Khudyakov Date: Tue, 20 Jan 2026 22:52:10 +0300 Subject: [PATCH 2/7] Add new API for vectors that not parametric in element type --- fixed-vector/Data/Vector/Fixed/Mono.hs | 978 +++++++++++++++++++++++++ fixed-vector/fixed-vector.cabal | 2 + 2 files changed, 980 insertions(+) create mode 100644 fixed-vector/Data/Vector/Fixed/Mono.hs diff --git a/fixed-vector/Data/Vector/Fixed/Mono.hs b/fixed-vector/Data/Vector/Fixed/Mono.hs new file mode 100644 index 0000000..8a0b148 --- /dev/null +++ b/fixed-vector/Data/Vector/Fixed/Mono.hs @@ -0,0 +1,978 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UnboxedTuples #-} +module Data.Vector.Fixed.Mono + ( -- * Vector type class + Prod(..) + , Vector + , Dim + , C.Arity + , C.ArityPeano + , C.Fun(..) + , length + -- ** Peano numbers + , PeanoNum(..) + , Peano + , N1, N2, N3, N4, N5, N6, N7, N8 + -- * Construction and destructions + -- $construction + + -- ** Constructors + , mk0 + , mk1 + , mk2 + , mk3 + , mk4 + , mk5 + , mk6 + , mk7 + , mk8 + , mkN + -- ** Pattern synonyms + , pattern V1 + , pattern V2 + , pattern V3 + , pattern V4 + -- * Functions + -- ** Creation + , replicate + , replicateM + , generate + , generateM + , unfoldr + , basis + -- ** Transformations + , head + , tail + , cons + , snoc + , concat + , reverse + -- ** Indexing & lenses + , C.Index + , (!) + , index + , set + , element + , elementTy + -- ** Maps + , map + , gmap + , mapM + , gmapM + , mapM_ + , imap + , igmap + , imapM + , igmapM + , imapM_ + , scanl + , scanl1 + -- , traverse + -- ** Folds + , foldl + , foldl' + , foldr + , foldl1 + , fold + , foldMap + , ifoldl + , ifoldl' + , ifoldr + , foldM + , ifoldM + -- *** Special folds + , sum + , maximum + , minimum + , and + , or + , all + , any + , find + -- ** Zips + , zipWith + , zipWith3 + , zipWithM + , zipWithM_ + , izipWith + , izipWith3 + , izipWithM + , izipWithM_ + -- *** Special zips + , eq + , ord + -- ** Conversion + , convert + , toList + , fromList + , fromList' + , fromListM + , fromFoldable + -- ** Continuation-based vectors + , C.ContVec + , vector + , cvec + -- * Instance deriving + , ViaFixed(..) + ) where + +import Control.DeepSeq (NFData(..)) +import Control.Monad.Primitive (PrimBase(..)) +import Data.Complex +import Data.Foldable qualified as T +import Data.Primitive.Types (Prim(..)) +import Foreign.Ptr (castPtr) +import Foreign.Storable (Storable(..)) + +import GHC.Exts (Proxy#,proxy#,Int(..),Int#,(+#),(*#)) +import GHC.ST (ST(..)) + +import Prelude (Eq(..),Ord(..),Show(..),Num(..),Functor,Applicative,Monad + ,Semigroup(..),Monoid(..) + ,Bool,Maybe(..),Ordering + ,fmap,(<$>),(.),($),shows,flip,undefined + ,type (~) + ) + + +import Data.Vector.Fixed (Only(..)) +import Data.Vector.Fixed qualified as F +import Data.Vector.Fixed.Cont qualified as C +import Data.Vector.Fixed.Cont (Dim,Add,ArityPeano,Peano,Index,PeanoNum(..), + N1,N2,N3,N4,N5,N6,N7,N8) + + + +---------------------------------------------------------------- +-- Classes +---------------------------------------------------------------- + + +class C.ArityPeano (Dim v) => Prod a v | v -> a where + inspect :: v -> C.Fun (Dim v) a r -> r + construct :: C.Fun (Dim v) a v + +class Prod a v => Vector a v + +-- | Convert regular vector to continuation based one. +cvec :: (Prod a v) => v -> C.ContVec (Dim v) a +cvec v = C.ContVec (inspect v) +{-# INLINE[0] cvec #-} + +-- | Convert continuation to the vector. +vector :: (Prod a v) => C.ContVec (Dim v) a -> v +vector = C.runContVec construct +{-# INLINE[1] vector #-} + +{-# RULES +"cvec/vector[mono]" forall v. + cvec (vector v) = v + #-} + + + +---------------------------------------------------------------- +-- Constructors +---------------------------------------------------------------- + +mk0 :: forall v a. (Vector a v, Dim v ~ 'Z) => v +mk0 = vector C.empty +{-# INLINE mk0 #-} + +mk1 :: forall v a. (Vector a v, Dim v ~ N1) => a -> v +mk1 a1 = vector $ C.mk1 a1 +{-# INLINE mk1 #-} + +mk2 :: forall v a. (Vector a v, Dim v ~ N2) => a -> a -> v +mk2 a1 a2 = vector $ C.mk2 a1 a2 +{-# INLINE mk2 #-} + +mk3 :: forall v a. (Vector a v, Dim v ~ N3) => a -> a -> a -> v +mk3 a1 a2 a3 = vector $ C.mk3 a1 a2 a3 +{-# INLINE mk3 #-} + +mk4 :: forall v a. (Vector a v, Dim v ~ N4) => a -> a -> a -> a -> v +mk4 a1 a2 a3 a4 = vector $ C.mk4 a1 a2 a3 a4 +{-# INLINE mk4 #-} + +mk5 :: forall v a. (Vector a v, Dim v ~ N5) => a -> a -> a -> a -> a -> v +mk5 a1 a2 a3 a4 a5 = vector $ C.mk5 a1 a2 a3 a4 a5 +{-# INLINE mk5 #-} + +mk6 :: forall v a. (Vector a v, Dim v ~ N6) => a -> a -> a -> a -> a -> a -> v +mk6 a1 a2 a3 a4 a5 a6 = vector $ C.mk6 a1 a2 a3 a4 a5 a6 +{-# INLINE mk6 #-} + +mk7 :: forall v a. (Vector a v, Dim v ~ N7) => a -> a -> a -> a -> a -> a -> a -> v +mk7 a1 a2 a3 a4 a5 a6 a7 = vector $ C.mk7 a1 a2 a3 a4 a5 a6 a7 +{-# INLINE mk7 #-} + +mk8 :: forall v a. (Vector a v, Dim v ~ N8) => a -> a -> a -> a -> a -> a -> a -> a -> v +mk8 a1 a2 a3 a4 a5 a6 a7 a8 = vector $ C.mk8 a1 a2 a3 a4 a5 a6 a7 a8 +{-# INLINE mk8 #-} + +-- | N-ary constructor. Despite scary signature it's just N-ary +-- function with additional type parameter which is used to fix type +-- of vector being constructed. It could be used as: +-- +-- > v = mkN (Proxy :: Proxy (Int,Int,Int)) 1 2 3 +-- +-- or using @TypeApplications@ syntax: +-- +-- > v = mkN (Proxy @(Int,Int,Int)) 1 2 3 +-- +-- or if type of @v@ is fixed elsewhere +-- +-- > v = mkN [v] 1 2 3 +mkN :: forall proxy v a. (Vector a v) + => proxy v -> C.Fn (Dim v) a v +mkN _ = C.unFun (construct :: C.Fun (Dim v) a v) + +---------------------------------------------------------------- +-- Generic functions +---------------------------------------------------------------- + +-- | Length of vector. Function doesn't evaluate its argument. +length :: forall v. C.ArityPeano (Dim v) => v -> Int +{-# INLINE length #-} +length _ = C.peanoToInt (proxy# @(Dim v)) + +-- | Replicate value /n/ times. +-- +-- Examples: +-- +-- >>> import Data.Vector.Fixed.Boxed (Vec2) +-- >>> replicate 1 :: Vec2 Int +-- [1,1] +-- +-- >>> replicate 2 :: (Double,Double,Double) +-- (2.0,2.0,2.0) +-- +-- >>> import Data.Vector.Fixed.Boxed (Vec4) +-- >>> replicate "foo" :: Vec4 String +-- ["foo","foo","foo","foo"] +replicate :: forall v a. Vector a v => a -> v +{-# INLINE replicate #-} +replicate + = vector . C.replicate + + +-- | Execute monadic action for every element of vector. +-- +-- Examples: +-- +-- >>> import Data.Vector.Fixed.Boxed (Vec2,Vec3) +-- >>> replicateM (Just 3) :: Maybe (Vec3 Int) +-- Just [3,3,3] +-- >>> replicateM (putStrLn "Hi!") :: IO (Vec2 ()) +-- Hi! +-- Hi! +-- [(),()] +replicateM :: forall v f a. (Vector a v, Applicative f) => f a -> f (v) +{-# INLINE replicateM #-} +replicateM + = fmap vector . C.replicateM + + +-- | Unit vector along Nth axis. If index is larger than vector +-- dimensions returns zero vector. +-- +-- Examples: +-- +-- >>> import Data.Vector.Fixed.Boxed (Vec3) +-- >>> basis 0 :: Vec3 Int +-- [1,0,0] +-- >>> basis 1 :: Vec3 Int +-- [0,1,0] +-- >>> basis 3 :: Vec3 Int +-- [0,0,0] +basis :: forall v a. (Vector a v, Num a) => Int -> v +{-# INLINE basis #-} +basis = vector . C.basis + + +-- | Unfold vector. +unfoldr :: forall v a b. (Vector a v) => (b -> (a,b)) -> b -> v +{-# INLINE unfoldr #-} +unfoldr f = vector . C.unfoldr f + + +-- | Generate vector from function which maps element's index to its +-- value. +-- +-- Examples: +-- +-- >>> import Data.Vector.Fixed.Unboxed (Vec4) +-- >>> generate (^2) :: Vec4 Int +-- [0,1,4,9] +generate :: forall v a. (Vector a v) => (Int -> a) -> v +{-# INLINE generate #-} +generate = vector . C.generate + + +-- | Generate vector from monadic function which maps element's index +-- to its value. +generateM :: forall v f a. (Applicative f, Vector a v) => (Int -> f a) -> f v +{-# INLINE generateM #-} +generateM = fmap vector . C.generateM + + + +---------------------------------------------------------------- + +-- | First element of vector. +-- +-- Examples: +-- +-- >>> import Data.Vector.Fixed.Boxed (Vec3) +-- >>> let x = mk3 1 2 3 :: Vec3 Int +-- >>> head x +-- 1 +head :: forall v k a. (Vector a v, Dim v ~ 'S k) => v -> a +{-# INLINE head #-} +head = C.head . cvec + + +-- | Tail of vector. +-- +-- Examples: +-- +-- >>> import Data.Complex +-- >>> tail (1,2,3) :: Complex Double +-- 2.0 :+ 3.0 +tail :: forall v w a. (Vector a v, Vector a w, Dim v ~ 'S (Dim w)) + => v -> w +{-# INLINE tail #-} +tail = vector . C.tail . cvec + +-- | Cons element to the vector +cons :: forall v w a. (Vector a v, Vector a w, Dim w ~ 'S (Dim v)) + => a -> v -> w +{-# INLINE cons #-} +cons a = vector . C.cons a . cvec + +-- | Append element to the vector +snoc :: forall v w a. (Vector a v, Vector a w, Dim w ~ 'S (Dim v)) + => a -> v -> w +{-# INLINE snoc #-} +snoc a = vector . C.snoc a . cvec + +concat :: forall v u w a. + ( Vector a v, Vector a u, Vector a w + , (Dim v `Add` Dim u) ~ Dim w + ) + => v -> u -> w +{-# INLINE concat #-} +concat v u = vector $ C.concat (cvec v) (cvec u) + +-- | Reverse order of elements in the vector +reverse :: forall v a. Vector a v => v -> v +reverse = vector . C.reverse . cvec +{-# INLINE reverse #-} + + +-- | Retrieve vector's element at index. Generic implementation is +-- /O(n)/ but more efficient one is used when possible. +(!) :: forall v a. (Vector a v) => v -> Int -> a +{-# INLINE (!) #-} +v ! i = C.index i (cvec v) + +-- | Get element from vector at statically known index +index :: forall v k a proxy. (Vector a v, Index (Peano k) (Dim v)) + => v -> proxy k -> a +{-# INLINE index #-} +index v _ = inspect v (C.getF (proxy# @(Peano k))) + +-- | Set n'th element in the vector +set :: forall v k a proxy. (Vector a v, Index (Peano k) (Dim v)) + => proxy k -> a -> v -> v +{-# INLINE set #-} +set _ a v + = inspect v + $ C.putF (proxy# @(Peano k)) a construct + +-- | Twan van Laarhoven's lens for element of vector +element :: forall v f a. (Vector a v, Functor f) => Int -> (a -> f a) -> (v -> f v) +{-# INLINE element #-} +element i f v = vector `fmap` C.element i f (cvec v) + +-- | Twan van Laarhoven's lens for element of vector with statically +-- known index. +elementTy + :: forall v f k a proxy. (Vector a v, Index (Peano k) (Dim v), Functor f) + => proxy k -> (a -> f a) -> (v -> f v) +{-# INLINE elementTy #-} +elementTy _ f v + = inspect v (C.lensF (proxy# @(Peano k)) f construct) + +-- | Left fold over vector +foldl :: forall v b a. Vector a v => (b -> a -> b) -> b -> v -> b +{-# INLINE foldl #-} +foldl f x = C.foldl f x + . cvec + +-- | Strict left fold over vector +foldl' :: forall v b a. Vector a v => (b -> a -> b) -> b -> v -> b +{-# INLINE foldl' #-} +foldl' f x = C.foldl' f x + . cvec + +-- | Right fold over vector +foldr :: forall v b a. Vector a v => (a -> b -> b) -> b -> v -> b +{-# INLINE foldr #-} +foldr f x = C.foldr f x + . cvec + + +-- | Left fold over vector +foldl1 :: forall v a k. (Vector a v, Dim v ~ 'S k) => (a -> a -> a) -> v -> a +{-# INLINE foldl1 #-} +foldl1 f = C.foldl1 f + . cvec + +-- | Combine the elements of a structure using a monoid. Similar to +-- 'T.fold' +fold :: forall v m. (Vector m v, Monoid m) => v -> m +{-# INLINE fold #-} +fold = T.fold + . cvec + +-- | Map each element of the structure to a monoid, +-- and combine the results. Similar to 'T.foldMap' +foldMap :: forall v m a. (Vector a v, Monoid m) => (a -> m) -> v -> m +{-# INLINE foldMap #-} +foldMap f = T.foldMap f + . cvec + +-- | Right fold over vector +ifoldr :: forall v b a. Vector a v => (Int -> a -> b -> b) -> b -> v -> b +{-# INLINE ifoldr #-} +ifoldr f x = C.ifoldr f x + . cvec + +-- | Left fold over vector. Function is applied to each element and +-- its index. +ifoldl :: forall v b a. Vector a v => (b -> Int -> a -> b) -> b -> v -> b +{-# INLINE ifoldl #-} +ifoldl f z = C.ifoldl f z + . cvec + +-- | Strict left fold over vector. Function is applied to each element +-- and its index. +ifoldl' :: forall v b a. Vector a v => (b -> Int -> a -> b) -> b -> v -> b +{-# INLINE ifoldl' #-} +ifoldl' f z = C.ifoldl' f z + . cvec + +-- | Monadic fold over vector. +foldM :: forall v m b a. (Vector a v, Monad m) => (b -> a -> m b) -> b -> v -> m b +{-# INLINE foldM #-} +foldM f x = C.foldM f x . cvec + +-- | Left monadic fold over vector. Function is applied to each element and +-- its index. +ifoldM :: forall v m b a. (Vector a v, Monad m) => (b -> Int -> a -> m b) -> b -> v -> m b +{-# INLINE ifoldM #-} +ifoldM f x = C.ifoldM f x . cvec + + +---------------------------------------------------------------- + +-- | Sum all elements in the vector. +sum :: forall v a. (Vector a v, Num a) => v -> a +sum = C.sum . cvec +{-# INLINE sum #-} + +-- | Maximal element of vector. +-- +-- Examples: +-- +-- >>> import Data.Vector.Fixed.Boxed (Vec3) +-- >>> let x = mk3 1 2 3 :: Vec3 Int +-- >>> maximum x +-- 3 +maximum :: forall v a k. (Vector a v, Dim v ~ S k, Ord a) => v -> a +maximum = C.maximum . cvec +{-# INLINE maximum #-} + +-- | Minimal element of vector. +-- +-- Examples: +-- +-- >>> import Data.Vector.Fixed.Boxed (Vec3) +-- >>> let x = mk3 1 2 3 :: Vec3 Int +-- >>> minimum x +-- 1 +minimum :: forall v a k. (Vector a v, Dim v ~ S k, Ord a) => v -> a +minimum = C.minimum . cvec +{-# INLINE minimum #-} + +-- | Conjunction of all elements of a vector. +and :: forall v. (Vector Bool v) => v -> Bool +and = C.and . cvec +{-# INLINE and #-} + +-- | Disjunction of all elements of a vector. +or :: forall v. (Vector Bool v) => v -> Bool +or = C.or . cvec +{-# INLINE or #-} + +-- | Determines whether all elements of vector satisfy predicate. +all :: forall v a. (Vector a v) => (a -> Bool) -> v -> Bool +all f = (C.all f) . cvec +{-# INLINE all #-} + +-- | Determines whether any of element of vector satisfy predicate. +any :: forall v a. (Vector a v) => (a -> Bool) -> v -> Bool +any f = (C.any f) . cvec +{-# INLINE any #-} + +-- | The 'find' function takes a predicate and a vector and returns +-- the leftmost element of the vector matching the predicate, +-- or 'Nothing' if there is no such element. +find :: forall v a. (Vector a v) => (a -> Bool) -> v -> Maybe a +find f = (C.find f) . cvec +{-# INLINE find #-} + +---------------------------------------------------------------- + +-- | Test two vectors for equality. +-- +-- Examples: +-- +-- >>> import Data.Vector.Fixed.Boxed (Vec2) +-- >>> let v0 = basis 0 :: Vec2 Int +-- >>> let v1 = basis 1 :: Vec2 Int +-- >>> v0 `eq` v0 +-- True +-- >>> v0 `eq` v1 +-- False +eq :: (Vector a v, Eq a) => v -> v -> Bool +{-# INLINE eq #-} +eq v w = C.and + $ C.zipWith (==) (cvec v) (cvec w) + + +-- | Lexicographic ordering of two vectors. +ord :: (Vector a v, Ord a) => v -> v -> Ordering +{-# INLINE ord #-} +ord v w = C.foldl mappend mempty + $ C.zipWith compare (cvec v) (cvec w) + + +---------------------------------------------------------------- + +-- | Map over vector +map :: forall v a. (Vector a v) => (a -> a) -> v -> v +{-# INLINE map #-} +map f = vector + . C.map f + . cvec + +-- | Map over vector +gmap :: forall v w a b. (Vector a v, Vector b w, Dim v ~ Dim w) => (a -> b) -> v -> w +{-# INLINE gmap #-} +gmap f = vector + . C.map f + . cvec + +-- | Effectful map over vector. +mapM :: forall v f a. (Vector a v, Applicative f) => (a -> f a) -> v -> f v +{-# INLINE mapM #-} +mapM f = fmap vector + . C.mapM f + . cvec + +-- | Effectful map over vector. +gmapM :: forall v w f a b. (Vector a v, Vector b w, Applicative f, Dim v ~ Dim w) + => (a -> f b) -> v -> f w +{-# INLINE gmapM #-} +gmapM f = fmap vector + . C.mapM f + . cvec + +-- | Apply monadic action to each element of vector and ignore result. +mapM_ :: forall v f b a. (Vector a v, Applicative f) => (a -> f b) -> v -> f () +{-# INLINE mapM_ #-} +mapM_ f = C.mapM_ f + . cvec + + +-- | Apply function to every element of the vector and its index. +imap :: forall v a. (Vector a v) => (Int -> a -> a) -> v -> v +{-# INLINE imap #-} +imap f = vector + . C.imap f + . cvec + +-- | Apply function to every element of the vector and its index. +igmap :: forall v w a b. (Vector a v, Vector b w, Dim v ~ Dim w) + => (Int -> a -> b) -> v -> w +{-# INLINE igmap #-} +igmap f = vector + . C.imap f + . cvec + +-- | Apply monadic function to every element of the vector and its index. +imapM :: forall v f a. (Vector a v, Applicative f) + => (Int -> a -> f a) -> v -> f v +{-# INLINE imapM #-} +imapM f = fmap vector + . C.imapM f + . cvec + +-- | Apply monadic function to every element of the vector and its index. +igmapM :: forall v w f a b. (Vector a v, Vector b w, Dim v ~ Dim w, Applicative f) + => (Int -> a -> f b) -> v -> f w +{-# INLINE igmapM #-} +igmapM f = fmap vector + . C.imapM f + . cvec + +-- | Apply monadic function to every element of the vector and its +-- index and discard result. +imapM_ :: forall v f b a. (Vector a v, Applicative f) => (Int -> a -> f b) -> v -> f () +{-# INLINE imapM_ #-} +imapM_ f = C.imapM_ f + . cvec + +-- | Left scan over vector +scanl :: forall v w a b. (Vector a v, Vector b w, Dim w ~ 'S (Dim v)) + => (b -> a -> b) -> b -> v -> w +{-# INLINE scanl #-} +scanl f x0 = vector . C.scanl f x0 . cvec + +-- | Left scan over vector +scanl1 :: forall v a. (Vector a v) + => (a -> a -> a) -> v -> v +{-# INLINE scanl1 #-} +scanl1 f = vector . C.scanl1 f . cvec + + + +---------------------------------------------------------------- + +-- | Zip two vector together using function. +-- +-- Examples: +-- +-- >>> import Data.Vector.Fixed.Boxed (Vec3) +-- >>> let b0 = basis 0 :: Vec3 Int +-- >>> let b1 = basis 1 :: Vec3 Int +-- >>> let b2 = basis 2 :: Vec3 Int +-- >>> let vplus x y = zipWith (+) x y +-- >>> vplus b0 b1 +-- [1,1,0] +-- >>> vplus b0 b2 +-- [1,0,1] +-- >>> vplus b1 b2 +-- [0,1,1] +zipWith :: forall v a. (Vector a v) + => (a -> a -> a) -> v -> v -> v +{-# INLINE zipWith #-} +zipWith f v u = vector + $ C.zipWith f (cvec v) (cvec u) + +-- | Zip three vector together +zipWith3 + :: forall v a. (Vector a v) + => (a -> a -> a -> a) + -> v -> v -> v -> v +{-# INLINE zipWith3 #-} +zipWith3 f v1 v2 v3 + = vector + $ C.zipWith3 f (cvec v1) (cvec v2) (cvec v3) + +-- | Zip two vector together using monadic function. +zipWithM :: forall v f a. (Vector a v, Applicative f) + => (a -> a -> f a) -> v -> v -> f v +{-# INLINE zipWithM #-} +zipWithM f v u = fmap vector + $ C.zipWithM f (cvec v) (cvec u) + +-- | Zip two vector elementwise using monadic function and discard +-- result +zipWithM_ + :: forall v f b a. (Vector a v, Applicative f) + => (a -> a -> f b) -> v -> v -> f () +{-# INLINE zipWithM_ #-} +zipWithM_ f xs ys = C.zipWithM_ f (cvec xs) (cvec ys) + +-- | Zip two vector together using function which takes element index +-- as well. +izipWith :: forall v a. (Vector a v) + => (Int -> a -> a -> a) -> v -> v -> v +{-# INLINE izipWith #-} +izipWith f v u = vector + $ C.izipWith f (cvec v) (cvec u) + +-- | Zip three vector together +izipWith3 + :: forall v a. (Vector a v) + => (Int -> a -> a -> a -> a) + -> v -> v -> v + -> v +{-# INLINE izipWith3 #-} +izipWith3 f v1 v2 v3 + = vector + $ C.izipWith3 f (cvec v1) (cvec v2) (cvec v3) + +-- | Zip two vector together using monadic function which takes element +-- index as well.. +izipWithM :: forall v f a. (Vector a v, Applicative f) + => (Int -> a -> a -> f a) -> v -> v -> f v +{-# INLINE izipWithM #-} +izipWithM f v u = fmap vector + $ C.izipWithM f (cvec v) (cvec u) + +-- | Zip two vector elementwise using monadic function and discard +-- result +izipWithM_ + :: forall v f b a. (Vector a v, Applicative f) + => (Int -> a -> a -> f b) -> v -> v -> f () +{-# INLINE izipWithM_ #-} +izipWithM_ f xs ys = C.izipWithM_ f (cvec xs) (cvec ys) + + +---------------------------------------------------------------- + +-- | Convert between different vector types +convert :: forall v w a. (Vector a v, Vector a w, Dim v ~ Dim w) => v -> w +{-# INLINE convert #-} +convert = vector . cvec + +-- | Convert vector to the list +toList :: forall v a. (Vector a v) => v -> [a] +toList = foldr (:) [] +{-# INLINE toList #-} + +-- | Create vector form list. Will throw error if list is shorter than +-- resulting vector. +fromList :: forall v a. (Vector a v) => [a] -> v +{-# INLINE fromList #-} +fromList = vector . C.fromList + +-- | Create vector form list. Will throw error if list has different +-- length from resulting vector. +fromList' :: forall v a. (Vector a v) => [a] -> v +{-# INLINE fromList' #-} +fromList' = vector . C.fromList' + +-- | Create vector form list. Will return @Nothing@ if list has different +-- length from resulting vector. +fromListM :: forall v a. (Vector a v) => [a] -> Maybe v +{-# INLINE fromListM #-} +fromListM = fmap vector . C.fromListM + +-- | Create vector from 'Foldable' data type. Will return @Nothing@ if +-- data type different number of elements that resulting vector. +fromFoldable :: forall v f a. (Vector a v, T.Foldable f) => f a -> Maybe v +{-# INLINE fromFoldable #-} +fromFoldable = fromListM . T.toList + + + + +---------------------------------------------------------------- +-- +---------------------------------------------------------------- + +-- | Newtype for deriving instances. +newtype ViaFixed a v = ViaFixed v + +instance (Prod a v) => Prod a (ViaFixed a v) where + inspect (ViaFixed v) = inspect v + construct = ViaFixed <$> construct +instance (Prod a v) => Vector a (ViaFixed a v) + +type instance Dim (ViaFixed a v) = Dim v + +instance (Prod a v, Show a) => Show (ViaFixed a v) where + showsPrec _ = shows . toList + +instance (Prod a v, Eq a) => Eq (ViaFixed a v) where + (==) = eq + {-# INLINE (==) #-} + +instance (Prod a v, Ord a) => Ord (ViaFixed a v) where + compare = ord + {-# INLINE compare #-} + +instance (Prod a v, NFData a) => NFData (ViaFixed a v) where + rnf = foldl (\() a -> rnf a) () + {-# INLINE rnf #-} + +instance (Prod a v, Semigroup a) => Semigroup (ViaFixed a v) where + (<>) = zipWith (<>) + {-# INLINE (<>) #-} + +instance (Prod a v, Monoid a) => Monoid (ViaFixed a v) where + mempty = replicate mempty + {-# INLINE mempty #-} + +instance (Prod a v, Storable a) => Storable (ViaFixed a v) where + alignment _ = alignment (undefined :: a) + sizeOf _ = sizeOf (undefined :: a) * C.peanoToInt (proxy# @(Dim v)) + peek p = generateM (peekElemOff (castPtr p)) + poke p = imapM_ (pokeElemOff (castPtr p)) + {-# INLINE alignment #-} + {-# INLINE sizeOf #-} + {-# INLINE peek #-} + {-# INLINE poke #-} + +instance (Prod a v, Prim a) => Prim (ViaFixed a v) where + sizeOf# _ = sizeOf# (undefined :: a) *# dim where + dim = case C.peanoToInt (proxy# @(Dim v)) of I# i -> i + alignment# _ = alignment# (undefined :: a) + {-# INLINE sizeOf# #-} + {-# INLINE alignment# #-} + -- Bytearray + indexByteArray# ba k + = generate $ \(I# i) -> indexByteArray# ba (off +# i) + where + off = vectorOff (proxy# @(Dim v)) k + readByteArray# ba k + = internal + $ generateM + $ \(I# i) -> ST (\s -> readByteArray# ba (off +# i) s) + where + off = vectorOff (proxy# @(Dim v)) k + writeByteArray# ba k vec = + case loop of + ST st -> \s -> case st s of + (# s', () #) -> s' + where + off = vectorOff (proxy# @(Dim v)) k + loop = flip imapM_ vec $ \(I# i) a -> ST $ \s -> + (# writeByteArray# ba (off +# i) a s, () #) + {-# INLINE indexByteArray# #-} + {-# INLINE readByteArray# #-} + {-# INLINE writeByteArray# #-} + -- Addr + indexOffAddr# addr k + = generate $ \(I# i) -> indexOffAddr# addr (off +# i) + where + off = vectorOff (proxy# @(Dim v)) k + readOffAddr# ba k + = internal + $ generateM + $ \(I# i) -> ST (\s -> readOffAddr# ba (off +# i) s) + where + off = vectorOff (proxy# @(Dim v)) k + writeOffAddr# addr k vec = + case loop of + ST st -> \s -> case st s of + (# s', () #) -> s' + where + off = vectorOff (proxy# @(Dim v)) k + loop = flip imapM_ vec $ \(I# i) a -> ST $ \s -> + (# writeOffAddr# addr (off +# i) a s, () #) + {-# INLINE indexOffAddr# #-} + {-# INLINE readOffAddr# #-} + {-# INLINE writeOffAddr# #-} + + +vectorOff :: (ArityPeano n) => Proxy# n -> Int# -> Int# +{-# INLINE vectorOff #-} +vectorOff n k = + case C.peanoToInt n of + I# dim -> dim *# k + +---------------------------------------------------------------- +-- Patterns +---------------------------------------------------------------- + +pattern V1 :: (Vector a v, Dim v ~ N1) => a -> v +pattern V1 x <- (convert -> (Only x)) where + V1 x = mk1 x +{-# INLINE V1 #-} +{-# COMPLETE V1 #-} + +pattern V2 :: (Vector a v, Dim v ~ N2) => a -> a -> v +pattern V2 x y <- (convert -> (x,y)) where + V2 x y = mk2 x y +{-# INLINE V2 #-} +{-# COMPLETE V2 #-} + +pattern V3 :: (Vector a v, Dim v ~ N3) => a -> a -> a -> v +pattern V3 x y z <- (convert -> (x,y,z)) where + V3 x y z = mk3 x y z +{-# INLINE V3 #-} +{-# COMPLETE V3 #-} + +pattern V4 :: (Vector a v, Dim v ~ N4) => a -> a -> a -> a -> v +pattern V4 t x y z <- (convert -> (t,x,y,z)) where + V4 t x y z = mk4 t x y z +{-# INLINE V4 #-} +{-# COMPLETE V4 #-} + +---------------------------------------------------------------- +-- Instances +---------------------------------------------------------------- + +instance Prod a (Complex a) where + inspect (r :+ i) (C.Fun f) = f r i + construct = C.Fun (:+) + {-# INLINE inspect #-} + {-# INLINE construct #-} +instance Vector a (Complex a) + +instance Prod a (Only a) where + inspect = F.inspect + construct = F.construct + {-# INLINE inspect #-} + {-# INLINE construct #-} +instance Vector a (Only a) + + +instance (a1 ~ a2) => Prod a1 (a1, a2) where + inspect (a1, a2) (C.Fun f) = f a1 a2 + construct = C.Fun (,) + {-# INLINE inspect #-} + {-# INLINE construct #-} + +instance (a1 ~ a2, a2 ~ a3) => Prod a1 (a1, a2, a3) where + inspect (a1, a2, a3) (C.Fun f) = f a1 a2 a3 + construct = C.Fun (,,) + {-# INLINE inspect #-} + {-# INLINE construct #-} + +instance (a1 ~ a2, a2 ~ a3, a3 ~ a4) => Prod a1 (a1, a2, a3, a4) where + inspect (a1, a2, a3, a4) (C.Fun f) = f a1 a2 a3 a4 + construct = C.Fun (,,,) + {-# INLINE inspect #-} + {-# INLINE construct #-} + +instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5) => Prod a1 (a1, a2, a3, a4, a5) where + inspect (a1, a2, a3, a4, a5) (C.Fun f) = f a1 a2 a3 a4 a5 + construct = C.Fun (,,,,) + {-# INLINE inspect #-} + {-# INLINE construct #-} + +instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6 + ) => Prod a1 (a1, a2, a3, a4, a5, a6) where + inspect (a1, a2, a3, a4, a5, a6) (C.Fun f) = f a1 a2 a3 a4 a5 a6 + construct = C.Fun (,,,,,) + {-# INLINE inspect #-} + {-# INLINE construct #-} + +instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6, a6 ~ a7 + ) => Prod a1 (a1, a2, a3, a4, a5, a6, a7) where + inspect (a1, a2, a3, a4, a5, a6, a7) (C.Fun f) = f a1 a2 a3 a4 a5 a6 a7 + construct = C.Fun (,,,,,,) + {-# INLINE inspect #-} + {-# INLINE construct #-} + + + +instance (a1 ~ a2) => Vector a1 (a1, a2) +instance (a1 ~ a2, a2 ~ a3) => Vector a1 (a1, a2, a3) +instance (a1 ~ a2, a2 ~ a3, a3 ~ a4) => Vector a1 (a1, a2, a3, a4) +instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5) => Vector a1 (a1, a2, a3, a4, a5) +instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6 + ) => Vector a1 (a1, a2, a3, a4, a5, a6) +instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6, a6 ~ a7 + ) => Vector a1 (a1, a2, a3, a4, a5, a6, a7) diff --git a/fixed-vector/fixed-vector.cabal b/fixed-vector/fixed-vector.cabal index f9ce760..0056954 100644 --- a/fixed-vector/fixed-vector.cabal +++ b/fixed-vector/fixed-vector.cabal @@ -126,6 +126,7 @@ common language PatternSynonyms ViewPatterns TypeFamilies + FunctionalDependencies Library @@ -140,6 +141,7 @@ Library Data.Vector.Fixed.Cont Data.Vector.Fixed Data.Vector.Fixed.Generic + Data.Vector.Fixed.Mono -- Arrays Data.Vector.Fixed.Mutable Data.Vector.Fixed.Boxed From 563bac8eff645d46c484d537d05974b847eb690a Mon Sep 17 00:00:00 2001 From: Alexey Khudyakov Date: Tue, 20 Jan 2026 23:16:58 +0300 Subject: [PATCH 3/7] Add instances for vectors defined in library --- fixed-vector/Data/Vector/Fixed.hs | 39 +++++++++++++++++++-- fixed-vector/Data/Vector/Fixed/Boxed.hs | 7 ++++ fixed-vector/Data/Vector/Fixed/Mono.hs | 14 ++------ fixed-vector/Data/Vector/Fixed/Primitive.hs | 7 ++++ fixed-vector/Data/Vector/Fixed/Storable.hs | 7 ++++ fixed-vector/Data/Vector/Fixed/Strict.hs | 7 ++++ fixed-vector/Data/Vector/Fixed/Unboxed.hs | 9 +++++ 7 files changed, 76 insertions(+), 14 deletions(-) diff --git a/fixed-vector/Data/Vector/Fixed.hs b/fixed-vector/Data/Vector/Fixed.hs index 83e3ed3..241c54e 100644 --- a/fixed-vector/Data/Vector/Fixed.hs +++ b/fixed-vector/Data/Vector/Fixed.hs @@ -206,9 +206,10 @@ import GHC.TypeLits import GHC.Exts (Proxy#,proxy#,(*#),(+#),Int(..),Int#) import GHC.ST (ST(..)) -import Data.Vector.Fixed.Cont (Vector(..),Dim,length,ContVec,PeanoNum(..), - vector,cvec,empty,Arity,ArityPeano,Fun(..),accum,apply) -import Data.Vector.Fixed.Cont qualified as C +import Data.Vector.Fixed.Cont (Vector(..),Dim,length,ContVec,PeanoNum(..), + vector,cvec,empty,Arity,ArityPeano,Fun(..),accum,apply) +import Data.Vector.Fixed.Cont qualified as C +import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Internal as I import Prelude (Show(..),Eq(..),Ord(..),Num(..),Functor(..),id,(.),($),(<$>),undefined,flip,type(~)) @@ -271,6 +272,13 @@ instance Arity n => Vector (VecList n) a where inspect (VecList v) = inspect v {-# INLINE construct #-} {-# INLINE inspect #-} +instance Arity n => FM.Prod a (VecList n a) where + construct = construct + inspect = inspect + {-# INLINE construct #-} + {-# INLINE inspect #-} +instance Arity n => FM.Vector a (VecList n a) where + instance C.ArityPeano n => Vector (VecPeano n) a where construct = accum @@ -284,6 +292,12 @@ instance C.ArityPeano n => Vector (VecPeano n) a where step (Flip (Cons a xs)) = (a, Flip xs) {-# INLINE construct #-} {-# INLINE inspect #-} +instance C.ArityPeano n => FM.Prod a (VecPeano n a) where + construct = construct + inspect = inspect + {-# INLINE construct #-} + {-# INLINE inspect #-} +instance C.ArityPeano n => FM.Vector a (VecPeano n a) where newtype Flip f a n = Flip (f n a) newtype T_List a n k = T_List (VecPeano k a -> VecPeano n a) @@ -375,6 +389,12 @@ instance Vector Only a where inspect (Only a) (Fun f) = f a {-# INLINE construct #-} {-# INLINE inspect #-} +instance FM.Prod a (Only a) where + construct = construct + inspect = inspect + {-# INLINE construct #-} + {-# INLINE inspect #-} +instance FM.Vector a (Only a) where instance (Storable a) => Storable (Only a) where alignment = coerce (alignment @a) @@ -398,6 +418,12 @@ instance Vector Empty a where inspect _ (Fun b) = b {-# INLINE construct #-} {-# INLINE inspect #-} +instance FM.Prod a (Empty a) where + construct = construct + inspect = inspect + {-# INLINE construct #-} + {-# INLINE inspect #-} +instance FM.Vector a (Empty a) where type Tuple2 a = (a,a) type Tuple3 a = (a,a,a) @@ -423,6 +449,13 @@ instance Vector v a => Vector (ViaFixed v) a where {-# INLINE construct #-} {-# INLINE inspect #-} +instance Vector v a => FM.Prod a (ViaFixed v a) where + construct = ViaFixed <$> construct + inspect (ViaFixed v) = inspect v + {-# INLINE construct #-} + {-# INLINE inspect #-} +instance Vector v a => FM.Vector a (ViaFixed v a) where + instance (Vector v a, Show a) => Show (ViaFixed v a) where showsPrec = coerce (I.showsPrec @v @a) diff --git a/fixed-vector/Data/Vector/Fixed/Boxed.hs b/fixed-vector/Data/Vector/Fixed/Boxed.hs index 0a6b3fb..049829a 100644 --- a/fixed-vector/Data/Vector/Fixed/Boxed.hs +++ b/fixed-vector/Data/Vector/Fixed/Boxed.hs @@ -33,6 +33,7 @@ import Prelude ( Show(..),Eq(..),Ord(..),Functor(..),Monad(..) , ($!),error,(<$>),type(~)) import Data.Vector.Fixed hiding (index) +import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index) import qualified Data.Vector.Fixed.Cont as C import Data.Vector.Fixed.Cont (ArityPeano(..)) @@ -126,6 +127,12 @@ instance (Arity n) => Vector (Vec n) a where {-# INLINE construct #-} {-# INLINE inspect #-} {-# INLINE basicIndex #-} +instance (Arity n) => FM.Prod a (Vec n a) where + construct = constructVec + inspect = inspectVec + {-# INLINE construct #-} + {-# INLINE inspect #-} +instance (Arity n) => FM.Vector a (Vec n a) instance (Typeable n, Arity n, Data a) => Data (Vec n a) where gfoldl = C.gfoldl diff --git a/fixed-vector/Data/Vector/Fixed/Mono.hs b/fixed-vector/Data/Vector/Fixed/Mono.hs index 8a0b148..688b3fb 100644 --- a/fixed-vector/Data/Vector/Fixed/Mono.hs +++ b/fixed-vector/Data/Vector/Fixed/Mono.hs @@ -138,8 +138,8 @@ import Prelude (Eq(..),Ord(..),Show(..),Num(..),Functor,Applicative,Monad ) -import Data.Vector.Fixed (Only(..)) -import Data.Vector.Fixed qualified as F +-- import Data.Vector.Fixed (Only(..)) +-- import Data.Vector.Fixed qualified as F import Data.Vector.Fixed.Cont qualified as C import Data.Vector.Fixed.Cont (Dim,Add,ArityPeano,Peano,Index,PeanoNum(..), N1,N2,N3,N4,N5,N6,N7,N8) @@ -886,7 +886,7 @@ vectorOff n k = ---------------------------------------------------------------- pattern V1 :: (Vector a v, Dim v ~ N1) => a -> v -pattern V1 x <- (convert -> (Only x)) where +pattern V1 x <- (head -> x) where V1 x = mk1 x {-# INLINE V1 #-} {-# COMPLETE V1 #-} @@ -920,14 +920,6 @@ instance Prod a (Complex a) where {-# INLINE construct #-} instance Vector a (Complex a) -instance Prod a (Only a) where - inspect = F.inspect - construct = F.construct - {-# INLINE inspect #-} - {-# INLINE construct #-} -instance Vector a (Only a) - - instance (a1 ~ a2) => Prod a1 (a1, a2) where inspect (a1, a2) (C.Fun f) = f a1 a2 construct = C.Fun (,) diff --git a/fixed-vector/Data/Vector/Fixed/Primitive.hs b/fixed-vector/Data/Vector/Fixed/Primitive.hs index 1326744..b298b87 100644 --- a/fixed-vector/Data/Vector/Fixed/Primitive.hs +++ b/fixed-vector/Data/Vector/Fixed/Primitive.hs @@ -35,6 +35,7 @@ import Prelude (($),($!),undefined,seq,(<$>)) import Data.Vector.Fixed hiding (index) +import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index) import qualified Data.Vector.Fixed.Cont as C import Data.Vector.Fixed.Cont (ArityPeano(..)) @@ -106,6 +107,12 @@ instance (Arity n, Prim a) => Vector (Vec n) a where {-# INLINE construct #-} {-# INLINE inspect #-} {-# INLINE basicIndex #-} +instance (Arity n, Prim a) => FM.Prod a (Vec n a) where + construct = constructVec + inspect = inspectVec + {-# INLINE construct #-} + {-# INLINE inspect #-} +instance (Arity n, Prim a) => FM.Vector a (Vec n a) instance (Typeable n, Arity n, Prim a, Data a) => Data (Vec n a) where gfoldl = C.gfoldl diff --git a/fixed-vector/Data/Vector/Fixed/Storable.hs b/fixed-vector/Data/Vector/Fixed/Storable.hs index 0e9fade..e5891f6 100644 --- a/fixed-vector/Data/Vector/Fixed/Storable.hs +++ b/fixed-vector/Data/Vector/Fixed/Storable.hs @@ -40,6 +40,7 @@ import Prelude ( Show(..),Eq(..),Ord(..),Num(..),Monad(..),IO,Int , ($),undefined,seq,pure) import Data.Vector.Fixed hiding (index) +import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index, new,unsafeFreeze) import qualified Data.Vector.Fixed.Cont as C import Data.Vector.Fixed.Cont (ArityPeano(..)) @@ -143,6 +144,12 @@ instance (Arity n, Storable a) => Vector (Vec n) a where {-# INLINE construct #-} {-# INLINE inspect #-} {-# INLINE basicIndex #-} +instance (Arity n, Storable a) => FM.Prod a (Vec n a) where + construct = constructVec + inspect = inspectVec + {-# INLINE construct #-} + {-# INLINE inspect #-} +instance (Arity n, Storable a) => FM.Vector a (Vec n a) instance (Arity n, Storable a) => Storable (Vec n a) where sizeOf = defaultSizeOf diff --git a/fixed-vector/Data/Vector/Fixed/Strict.hs b/fixed-vector/Data/Vector/Fixed/Strict.hs index b0818bc..bcccc29 100644 --- a/fixed-vector/Data/Vector/Fixed/Strict.hs +++ b/fixed-vector/Data/Vector/Fixed/Strict.hs @@ -23,6 +23,7 @@ import Prelude ( Show(..),Eq(..),Ord(..),Functor(..),Monad(..) , ($!),error,(<$>),type (~)) import Data.Vector.Fixed hiding (index) +import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index) import qualified Data.Vector.Fixed.Cont as C import Data.Vector.Fixed.Cont (ArityPeano(..)) @@ -116,6 +117,12 @@ instance (Arity n) => Vector (Vec n) a where {-# INLINE construct #-} {-# INLINE inspect #-} {-# INLINE basicIndex #-} +instance (Arity n) => FM.Prod a (Vec n a) where + construct = constructVec + inspect = inspectVec + {-# INLINE construct #-} + {-# INLINE inspect #-} +instance (Arity n) => FM.Vector a (Vec n a) instance (Typeable n, Arity n, Data a) => Data (Vec n a) where gfoldl = C.gfoldl diff --git a/fixed-vector/Data/Vector/Fixed/Unboxed.hs b/fixed-vector/Data/Vector/Fixed/Unboxed.hs index ee99988..40e9698 100644 --- a/fixed-vector/Data/Vector/Fixed/Unboxed.hs +++ b/fixed-vector/Data/Vector/Fixed/Unboxed.hs @@ -48,6 +48,7 @@ import Prelude ( Show(..),Eq(..),Ord(..),Num(..),Applicative(..) import Data.Vector.Fixed (Dim,Vector(..),ViaFixed(..)) import Data.Vector.Fixed qualified as F import Data.Vector.Fixed.Cont qualified as C +import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Cont (Peano,Arity,ArityPeano,Fun(..),curryFirst) import Data.Vector.Fixed.Primitive qualified as P @@ -99,6 +100,14 @@ instance (Arity n, Unbox n a) => Vector (Vec n) a where {-# INLINE inspect #-} {-# INLINE construct #-} +instance (Arity n, Unbox n a) => FM.Prod a (Vec n a) where + construct = construct + inspect = inspect + {-# INLINE construct #-} + {-# INLINE inspect #-} + +instance (Arity n, Unbox n a) => FM.Vector a (Vec n a) + ---------------------------------------------------------------- From f5d0c8cf91b818d38f4838c5ba18f7f6947c6df2 Mon Sep 17 00:00:00 2001 From: Alexey Khudyakov Date: Tue, 20 Jan 2026 23:41:04 +0300 Subject: [PATCH 4/7] Add instances for instance packages --- .../Data/Vector/Fixed/Instances/QuickCheck.hs | 3 ++ .../Data/Vector/Fixed/Instances/Aeson.hs | 30 ++++++++++++++----- .../Data/Vector/Fixed/Instances/Binary.hs | 7 +++++ .../Data/Vector/Fixed/Instances/CBOR.hs | 20 +++++++++---- .../Data/Vector/Fixed/Instances/Cereal.hs | 7 +++++ 5 files changed, 53 insertions(+), 14 deletions(-) diff --git a/fixed-vector-QC/Data/Vector/Fixed/Instances/QuickCheck.hs b/fixed-vector-QC/Data/Vector/Fixed/Instances/QuickCheck.hs index 770c924..2537ea4 100644 --- a/fixed-vector-QC/Data/Vector/Fixed/Instances/QuickCheck.hs +++ b/fixed-vector-QC/Data/Vector/Fixed/Instances/QuickCheck.hs @@ -16,11 +16,14 @@ import qualified Data.Vector.Fixed.Strict as FF import qualified Data.Vector.Fixed.Unboxed as FU import qualified Data.Vector.Fixed.Primitive as FP import qualified Data.Vector.Fixed.Storable as FS +import qualified Data.Vector.Fixed.Mono as FM import Test.QuickCheck instance (Vector v a, Arbitrary a) => Arbitrary (ViaFixed v a) where arbitrary = F.replicateM arbitrary +instance (FM.Prod a v, Arbitrary a) => Arbitrary (FM.ViaFixed a v) where + arbitrary = FM.replicateM arbitrary deriving via ViaFixed (FB.Vec n) a instance (Arity n, Arbitrary a) => Arbitrary (FB.Vec n a) diff --git a/fixed-vector-aeson/Data/Vector/Fixed/Instances/Aeson.hs b/fixed-vector-aeson/Data/Vector/Fixed/Instances/Aeson.hs index 23fbd7a..f490aa5 100644 --- a/fixed-vector-aeson/Data/Vector/Fixed/Instances/Aeson.hs +++ b/fixed-vector-aeson/Data/Vector/Fixed/Instances/Aeson.hs @@ -2,6 +2,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} @@ -22,8 +23,10 @@ import qualified Data.Vector.Fixed.Strict as FF import qualified Data.Vector.Fixed.Unboxed as FU import qualified Data.Vector.Fixed.Primitive as FP import qualified Data.Vector.Fixed.Storable as FS +import qualified Data.Vector.Fixed.Mono as FM import Data.Aeson import Data.Aeson.Types +import Data.Coerce import qualified Data.Vector as V import qualified Data.Vector.Mutable as MV @@ -35,32 +38,32 @@ import qualified Data.Vector.Mutable as MV -- | Generic implementation of 'parseJSON' for data types which are -- instances of 'Vector'. -fixedVectorParseJSON :: forall v a. (Vector v a, FromJSON a) => Value -> Parser (v a) +fixedVectorParseJSON :: forall v a. (FM.Prod a v, FromJSON a) => Value -> Parser v {-# INLINE fixedVectorParseJSON #-} fixedVectorParseJSON = withArray "fixed-vector" $ \arr -> do - let expected = F.length (undefined :: v a) + let expected = FM.length (undefined :: v) when (V.length arr /= expected) $ fail $ "Expecting array of length " ++ show expected - F.generateM $ \i -> parseJSON (arr V.! i) + coerce $ FM.generateM @(FM.ViaFixed a v) $ \i -> parseJSON (arr V.! i) -- | Generic implementation of 'toJSON' for data types which are -- instances of 'Vector'. -fixedVectorToJSON :: forall v a. (Vector v a, ToJSON a) => v a -> Value +fixedVectorToJSON :: forall v a. (FM.Prod a v, ToJSON a) => v -> Value {-# INLINE fixedVectorToJSON #-} fixedVectorToJSON v = Array $ runST $ do -- NOTE: (!) from fixed vector could have O(n) complexity so let -- fold over fixed vector. Access to vector _is_ O(1) vec <- MV.unsafeNew n - flip F.imapM_ v $ \i a -> MV.unsafeWrite vec i (toJSON a) + flip FM.imapM_ (FM.ViaFixed v) $ \i a -> MV.unsafeWrite vec i (toJSON a) V.unsafeFreeze vec where - n = F.length v + n = FM.length v -- | Generic implementation of 'toEncoding' for data types which are -- instances of 'Vector'. -fixedVectorToEncoding :: forall v a. (Vector v a, ToJSON a) => v a -> Encoding +fixedVectorToEncoding :: forall v a. (FM.Prod a v, ToJSON a) => v -> Encoding {-# INLINE fixedVectorToEncoding #-} -fixedVectorToEncoding = foldable . F.cvec +fixedVectorToEncoding = foldable . FM.cvec ---------------------------------------------------------------- @@ -68,8 +71,13 @@ fixedVectorToEncoding = foldable . F.cvec ---------------------------------------------------------------- instance (Vector v a, FromJSON a) => FromJSON (ViaFixed v a) where + parseJSON = fixedVectorParseJSON {-# INLINE parseJSON #-} + +instance (FM.Prod a v, FromJSON a) => FromJSON (FM.ViaFixed a v) where parseJSON = fixedVectorParseJSON + {-# INLINE parseJSON #-} + instance (Vector v a, ToJSON a) => ToJSON (ViaFixed v a) where toJSON = fixedVectorToJSON @@ -77,6 +85,12 @@ instance (Vector v a, ToJSON a) => ToJSON (ViaFixed v a) where {-# INLINE toJSON #-} {-# INLINE toEncoding #-} +instance (FM.Prod a v, ToJSON a) => ToJSON (FM.ViaFixed a v) where + toJSON = fixedVectorToJSON + toEncoding = fixedVectorToEncoding + {-# INLINE toJSON #-} + {-# INLINE toEncoding #-} + deriving via ViaFixed (FB.Vec n) a instance (Arity n, FromJSON a) => FromJSON (FB.Vec n a) diff --git a/fixed-vector-binary/Data/Vector/Fixed/Instances/Binary.hs b/fixed-vector-binary/Data/Vector/Fixed/Instances/Binary.hs index 6377d91..16b03ad 100644 --- a/fixed-vector-binary/Data/Vector/Fixed/Instances/Binary.hs +++ b/fixed-vector-binary/Data/Vector/Fixed/Instances/Binary.hs @@ -15,6 +15,7 @@ import qualified Data.Vector.Fixed.Strict as FF import qualified Data.Vector.Fixed.Unboxed as FU import qualified Data.Vector.Fixed.Primitive as FP import qualified Data.Vector.Fixed.Storable as FS +import qualified Data.Vector.Fixed.Mono as FM import Data.Binary (Binary(..)) instance (Vector v a, Binary a) => Binary (ViaFixed v a) where @@ -23,6 +24,12 @@ instance (Vector v a, Binary a) => Binary (ViaFixed v a) where {-# INLINE put #-} {-# INLINE get #-} +instance (FM.Prod a v, Binary a) => Binary (FM.ViaFixed a v) where + put = FM.mapM_ put + get = FM.replicateM get + {-# INLINE put #-} + {-# INLINE get #-} + deriving via ViaFixed (FB.Vec n) a instance (Arity n, Binary a) => Binary (FB.Vec n a) deriving via ViaFixed (FF.Vec n) a instance (Arity n, Binary a) => Binary (FF.Vec n a) deriving via ViaFixed (FP.Vec n) a instance (Arity n, Binary a, FP.Prim a) => Binary (FP.Vec n a) diff --git a/fixed-vector-cborg/Data/Vector/Fixed/Instances/CBOR.hs b/fixed-vector-cborg/Data/Vector/Fixed/Instances/CBOR.hs index 3a7d7ca..2181137 100644 --- a/fixed-vector-cborg/Data/Vector/Fixed/Instances/CBOR.hs +++ b/fixed-vector-cborg/Data/Vector/Fixed/Instances/CBOR.hs @@ -24,7 +24,8 @@ import qualified Data.Vector.Fixed.Strict as FF import qualified Data.Vector.Fixed.Unboxed as FU import qualified Data.Vector.Fixed.Primitive as FP import qualified Data.Vector.Fixed.Storable as FS - +import qualified Data.Vector.Fixed.Mono as FM +import Data.Coerce instance (Vector v a, Serialise a) => Serialise (ViaFixed v a) where encode = encodeFixedVector @@ -32,6 +33,12 @@ instance (Vector v a, Serialise a) => Serialise (ViaFixed v a) where {-# INLINE encode #-} {-# INLINE decode #-} +instance (FM.Prod a v, Serialise a) => Serialise (FM.ViaFixed a v) where + encode = encodeFixedVector + decode = decodeFixedVector + {-# INLINE encode #-} + {-# INLINE decode #-} + deriving via ViaFixed (FB.Vec n) a instance (Arity n, Serialise a) => Serialise (FB.Vec n a) deriving via ViaFixed (FF.Vec n) a instance (Arity n, Serialise a) => Serialise (FF.Vec n a) deriving via ViaFixed (FP.Vec n) a instance (Arity n, Serialise a, FP.Prim a) => Serialise (FP.Vec n a) @@ -49,15 +56,16 @@ instance Serialise (F.Empty a) where -- | Encode vector with statically known size as CBOR list. There's no -- type tag -encodeFixedVector :: (F.Vector v a, Serialise a) => v a -> Encoding +encodeFixedVector :: (FM.Prod a v, Serialise a) => v -> Encoding {-# INLINE encodeFixedVector #-} -encodeFixedVector v = encodeListLen (fromIntegral $ F.length v) - <> F.foldMap encode v +encodeFixedVector v + = encodeListLen (fromIntegral $ FM.length v) + <> FM.foldMap encode (FM.ViaFixed v) -- | Decode vector with statically known size as CBOR list. There's no -- type tag -decodeFixedVector :: forall v s a. (F.Vector v a, Serialise a) => Decoder s (v a) +decodeFixedVector :: forall v s a. (FM.Prod a v, Serialise a) => Decoder s v {-# INLINE decodeFixedVector #-} decodeFixedVector = do decodeListLenOf (fromIntegral $ peanoToInt (proxy# @(Dim v))) - F.replicateM decode + coerce $ FM.replicateM @(FM.ViaFixed a v) decode diff --git a/fixed-vector-cereal/Data/Vector/Fixed/Instances/Cereal.hs b/fixed-vector-cereal/Data/Vector/Fixed/Instances/Cereal.hs index 4f7581f..11493c6 100644 --- a/fixed-vector-cereal/Data/Vector/Fixed/Instances/Cereal.hs +++ b/fixed-vector-cereal/Data/Vector/Fixed/Instances/Cereal.hs @@ -15,6 +15,7 @@ import qualified Data.Vector.Fixed.Strict as FF import qualified Data.Vector.Fixed.Unboxed as FU import qualified Data.Vector.Fixed.Primitive as FP import qualified Data.Vector.Fixed.Storable as FS +import qualified Data.Vector.Fixed.Mono as FM import Data.Serialize (Serialize(..)) @@ -24,6 +25,12 @@ instance (Vector v a, Serialize a) => Serialize (ViaFixed v a) where {-# INLINE put #-} {-# INLINE get #-} +instance (FM.Prod a v, Serialize a) => Serialize (FM.ViaFixed a v) where + put = FM.mapM_ put + get = FM.replicateM get + {-# INLINE put #-} + {-# INLINE get #-} + deriving via ViaFixed (FB.Vec n) a instance (Arity n, Serialize a) => Serialize (FB.Vec n a) deriving via ViaFixed (FF.Vec n) a instance (Arity n, Serialize a) => Serialize (FF.Vec n a) deriving via ViaFixed (FP.Vec n) a instance (Arity n, Serialize a, FP.Prim a) => Serialize (FP.Vec n a) From 8c4e6481d2725a0c0563725a468087f3420cecc3 Mon Sep 17 00:00:00 2001 From: Alexey Khudyakov Date: Wed, 21 Jan 2026 00:04:38 +0300 Subject: [PATCH 5/7] Fix doctests --- fixed-vector/Data/Vector/Fixed/Mono.hs | 7 +++++++ fixed-vector/test/Doctests.hs | 1 + 2 files changed, 8 insertions(+) diff --git a/fixed-vector/Data/Vector/Fixed/Mono.hs b/fixed-vector/Data/Vector/Fixed/Mono.hs index 688b3fb..77fefaf 100644 --- a/fixed-vector/Data/Vector/Fixed/Mono.hs +++ b/fixed-vector/Data/Vector/Fixed/Mono.hs @@ -968,3 +968,10 @@ instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6 ) => Vector a1 (a1, a2, a3, a4, a5, a6) instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6, a6 ~ a7 ) => Vector a1 (a1, a2, a3, a4, a5, a6, a7) + + +-- $setup +-- +-- >>> import Data.Char +-- >>> import Prelude (Int,Bool(..),Double,IO,(^),String,putStrLn) + diff --git a/fixed-vector/test/Doctests.hs b/fixed-vector/test/Doctests.hs index 991cbdc..74244dd 100644 --- a/fixed-vector/test/Doctests.hs +++ b/fixed-vector/test/Doctests.hs @@ -66,4 +66,5 @@ exts = , "-XPatternSynonyms" , "-XViewPatterns" , "-XTypeFamilies" + , "-XFunctionalDependencies" ] From 1913e01b77337906a933bcd60b814851f4afcd52 Mon Sep 17 00:00:00 2001 From: Alexey Khudyakov Date: Thu, 22 Jan 2026 10:32:01 +0300 Subject: [PATCH 6/7] Add compat module for GHC 9.2 And update version bounds --- fixed-vector-QC/fixed-vector-QC.cabal | 15 +++++++-------- fixed-vector-aeson/fixed-vector-aeson.cabal | 15 +++++++-------- fixed-vector-binary/fixed-vector-binary.cabal | 15 +++++++-------- fixed-vector-cborg/fixed-vector-cborg.cabal | 15 +++++++-------- fixed-vector-cereal/fixed-vector-cereal.cabal | 15 +++++++-------- fixed-vector/Data/Vector/Fixed.hs | 3 ++- fixed-vector/Data/Vector/Fixed/Boxed.hs | 3 ++- fixed-vector/Data/Vector/Fixed/Compat.hs | 8 ++++++++ fixed-vector/Data/Vector/Fixed/Cont.hs | 5 ++--- fixed-vector/Data/Vector/Fixed/Mono.hs | 5 +---- fixed-vector/Data/Vector/Fixed/Strict.hs | 5 +++-- fixed-vector/Data/Vector/Fixed/Unboxed.hs | 3 ++- fixed-vector/fixed-vector.cabal | 5 +++-- 13 files changed, 58 insertions(+), 54 deletions(-) create mode 100644 fixed-vector/Data/Vector/Fixed/Compat.hs diff --git a/fixed-vector-QC/fixed-vector-QC.cabal b/fixed-vector-QC/fixed-vector-QC.cabal index bde25fa..1ccb0c0 100644 --- a/fixed-vector-QC/fixed-vector-QC.cabal +++ b/fixed-vector-QC/fixed-vector-QC.cabal @@ -17,13 +17,12 @@ extra-source-files: ChangeLog.md tested-with: - GHC ==8.10.7 - || ==9.0.1 - || ==9.2.8 - || ==9.4.7 - || ==9.6.6 - || ==9.8.2 - || ==9.10.1 + GHC ==9.4.7 + || ==9.6.7 + || ==9.8.4 + || ==9.10.2 + || ==9.12.2 + || ==9.14.1 source-repository head type: git @@ -32,7 +31,7 @@ source-repository head Library Ghc-options: -Wall Default-Language: Haskell2010 - Build-Depends: base >=4.14 && <5 + Build-Depends: base >=4.16 && <5 , fixed-vector >=2.0 , QuickCheck >=2.13 Exposed-modules: diff --git a/fixed-vector-aeson/fixed-vector-aeson.cabal b/fixed-vector-aeson/fixed-vector-aeson.cabal index 8ae8bf3..6dc0793 100644 --- a/fixed-vector-aeson/fixed-vector-aeson.cabal +++ b/fixed-vector-aeson/fixed-vector-aeson.cabal @@ -17,13 +17,12 @@ extra-source-files: ChangeLog.md tested-with: - GHC ==8.10.7 - || ==9.0.1 - || ==9.2.8 - || ==9.4.7 - || ==9.6.6 - || ==9.8.2 - || ==9.10.1 + GHC ==9.4.7 + || ==9.6.7 + || ==9.8.4 + || ==9.10.2 + || ==9.12.2 + || ==9.14.1 source-repository head type: git @@ -32,7 +31,7 @@ source-repository head Library Ghc-options: -Wall Default-Language: Haskell2010 - Build-Depends: base >=4.14 && <5 + Build-Depends: base >=4.16 && <5 , fixed-vector >=2.0 , aeson >=2 , vector diff --git a/fixed-vector-binary/fixed-vector-binary.cabal b/fixed-vector-binary/fixed-vector-binary.cabal index de2f23a..edbcaef 100644 --- a/fixed-vector-binary/fixed-vector-binary.cabal +++ b/fixed-vector-binary/fixed-vector-binary.cabal @@ -17,13 +17,12 @@ extra-source-files: ChangeLog.md tested-with: - GHC ==8.10.7 - || ==9.0.1 - || ==9.2.8 - || ==9.4.7 - || ==9.6.6 - || ==9.8.2 - || ==9.10.1 + GHC ==9.4.7 + || ==9.6.7 + || ==9.8.4 + || ==9.10.2 + || ==9.12.2 + || ==9.14.1 source-repository head type: git @@ -32,7 +31,7 @@ source-repository head Library Ghc-options: -Wall Default-Language: Haskell2010 - Build-Depends: base >=4.14 && <5 + Build-Depends: base >=4.16 && <5 , fixed-vector >=2.0 , binary Exposed-modules: diff --git a/fixed-vector-cborg/fixed-vector-cborg.cabal b/fixed-vector-cborg/fixed-vector-cborg.cabal index f67aea0..a670bce 100644 --- a/fixed-vector-cborg/fixed-vector-cborg.cabal +++ b/fixed-vector-cborg/fixed-vector-cborg.cabal @@ -17,13 +17,12 @@ extra-source-files: ChangeLog.md tested-with: - GHC ==8.10.7 - || ==9.0.1 - || ==9.2.8 - || ==9.4.7 - || ==9.6.6 - || ==9.8.2 - || ==9.10.1 + GHC ==9.4.7 + || ==9.6.7 + || ==9.8.4 + || ==9.10.2 + || ==9.12.2 + || ==9.14.1 source-repository head type: git @@ -32,7 +31,7 @@ source-repository head Library Ghc-options: -Wall Default-Language: Haskell2010 - Build-Depends: base >=4.14 && <5 + Build-Depends: base >=4.16 && <5 , fixed-vector >=2.0 , cborg , serialise diff --git a/fixed-vector-cereal/fixed-vector-cereal.cabal b/fixed-vector-cereal/fixed-vector-cereal.cabal index 0b5e0c6..ee2c94e 100644 --- a/fixed-vector-cereal/fixed-vector-cereal.cabal +++ b/fixed-vector-cereal/fixed-vector-cereal.cabal @@ -17,13 +17,12 @@ extra-source-files: ChangeLog.md tested-with: - GHC ==8.10.7 - || ==9.0.1 - || ==9.2.8 - || ==9.4.7 - || ==9.6.6 - || ==9.8.2 - || ==9.10.1 + GHC ==9.4.7 + || ==9.6.7 + || ==9.8.4 + || ==9.10.2 + || ==9.12.2 + || ==9.14.1 source-repository head type: git @@ -32,7 +31,7 @@ source-repository head Library Ghc-options: -Wall Default-Language: Haskell2010 - Build-Depends: base >=4.14 && <5 + Build-Depends: base >=4.16 && <5 , fixed-vector >=2.0 , cereal Exposed-modules: diff --git a/fixed-vector/Data/Vector/Fixed.hs b/fixed-vector/Data/Vector/Fixed.hs index 241c54e..5a83b6b 100644 --- a/fixed-vector/Data/Vector/Fixed.hs +++ b/fixed-vector/Data/Vector/Fixed.hs @@ -211,8 +211,9 @@ import Data.Vector.Fixed.Cont (Vector(..),Dim,length,ContVec,PeanoNum(..), import Data.Vector.Fixed.Cont qualified as C import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Internal as I +import Data.Vector.Fixed.Compat -import Prelude (Show(..),Eq(..),Ord(..),Num(..),Functor(..),id,(.),($),(<$>),undefined,flip,type(~)) +import Prelude (Show(..),Eq(..),Ord(..),Num(..),Functor(..),id,(.),($),(<$>),undefined,flip) -- $construction diff --git a/fixed-vector/Data/Vector/Fixed/Boxed.hs b/fixed-vector/Data/Vector/Fixed/Boxed.hs index 049829a..83696e7 100644 --- a/fixed-vector/Data/Vector/Fixed/Boxed.hs +++ b/fixed-vector/Data/Vector/Fixed/Boxed.hs @@ -30,8 +30,9 @@ import Foreign.Storable (Storable) import GHC.TypeLits import GHC.Exts (proxy#) import Prelude ( Show(..),Eq(..),Ord(..),Functor(..),Monad(..) - , ($!),error,(<$>),type(~)) + , ($!),error,(<$>)) +import Data.Vector.Fixed.Compat import Data.Vector.Fixed hiding (index) import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index) diff --git a/fixed-vector/Data/Vector/Fixed/Compat.hs b/fixed-vector/Data/Vector/Fixed/Compat.hs new file mode 100644 index 0000000..7c2e874 --- /dev/null +++ b/fixed-vector/Data/Vector/Fixed/Compat.hs @@ -0,0 +1,8 @@ +{-# LANGUAGE CPP #-} +-- | Compatibility for old GHC +module Data.Vector.Fixed.Compat + ( +#if MIN_VERSION_base(4,17,0) + type(~) +#endif + ) where diff --git a/fixed-vector/Data/Vector/Fixed/Cont.hs b/fixed-vector/Data/Vector/Fixed/Cont.hs index 02e6ca7..5276bb6 100644 --- a/fixed-vector/Data/Vector/Fixed/Cont.hs +++ b/fixed-vector/Data/Vector/Fixed/Cont.hs @@ -29,7 +29,7 @@ module Data.Vector.Fixed.Cont ( , shuffleFun , withFun , dimapFun - -- * Vector type class + -- * Vector type Boxedclass , Dim , Vector(..) , length @@ -136,9 +136,8 @@ import Prelude ( Bool(..), Int, Maybe(..), Either(..) , Eq(..), Ord(..), Num(..), Functor(..), Applicative(..), Monad(..) , Semigroup(..), Monoid(..) , (.), ($), (&&), (||), (<$>), id, error, otherwise, fst - , type(~) ) - +import Data.Vector.Fixed.Compat ---------------------------------------------------------------- -- Naturals diff --git a/fixed-vector/Data/Vector/Fixed/Mono.hs b/fixed-vector/Data/Vector/Fixed/Mono.hs index 77fefaf..020266e 100644 --- a/fixed-vector/Data/Vector/Fixed/Mono.hs +++ b/fixed-vector/Data/Vector/Fixed/Mono.hs @@ -134,12 +134,9 @@ import Prelude (Eq(..),Ord(..),Show(..),Num(..),Functor,Applicative,Monad ,Semigroup(..),Monoid(..) ,Bool,Maybe(..),Ordering ,fmap,(<$>),(.),($),shows,flip,undefined - ,type (~) ) - --- import Data.Vector.Fixed (Only(..)) --- import Data.Vector.Fixed qualified as F +import Data.Vector.Fixed.Compat import Data.Vector.Fixed.Cont qualified as C import Data.Vector.Fixed.Cont (Dim,Add,ArityPeano,Peano,Index,PeanoNum(..), N1,N2,N3,N4,N5,N6,N7,N8) diff --git a/fixed-vector/Data/Vector/Fixed/Strict.hs b/fixed-vector/Data/Vector/Fixed/Strict.hs index bcccc29..7649450 100644 --- a/fixed-vector/Data/Vector/Fixed/Strict.hs +++ b/fixed-vector/Data/Vector/Fixed/Strict.hs @@ -20,9 +20,10 @@ import Foreign.Storable (Storable) import GHC.TypeLits import GHC.Exts (proxy#) import Prelude ( Show(..),Eq(..),Ord(..),Functor(..),Monad(..) - , ($!),error,(<$>),type (~)) - + , ($!),error,(<$>)) + import Data.Vector.Fixed hiding (index) +import Data.Vector.Fixed.Compat import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index) import qualified Data.Vector.Fixed.Cont as C diff --git a/fixed-vector/Data/Vector/Fixed/Unboxed.hs b/fixed-vector/Data/Vector/Fixed/Unboxed.hs index 40e9698..ae34ac5 100644 --- a/fixed-vector/Data/Vector/Fixed/Unboxed.hs +++ b/fixed-vector/Data/Vector/Fixed/Unboxed.hs @@ -43,10 +43,11 @@ import Foreign.Storable (Storable) import GHC.TypeLits import GHC.Exts (Proxy#, proxy#) import Prelude ( Show(..),Eq(..),Ord(..),Num(..),Applicative(..) - , Int,Double,Float,Char,Bool(..),($),id,type (~)) + , Int,Double,Float,Char,Bool(..),($),id) import Data.Vector.Fixed (Dim,Vector(..),ViaFixed(..)) import Data.Vector.Fixed qualified as F +import Data.Vector.Fixed.Compat import Data.Vector.Fixed.Cont qualified as C import Data.Vector.Fixed.Mono qualified as FM import Data.Vector.Fixed.Cont (Peano,Arity,ArityPeano,Fun(..),curryFirst) diff --git a/fixed-vector/fixed-vector.cabal b/fixed-vector/fixed-vector.cabal index 0056954..1328828 100644 --- a/fixed-vector/fixed-vector.cabal +++ b/fixed-vector/fixed-vector.cabal @@ -59,12 +59,12 @@ extra-doc-files: ChangeLog.md tested-with: - GHC ==9.2.8 - || ==9.4.7 + GHC ==9.4.7 || ==9.6.7 || ==9.8.4 || ==9.10.2 || ==9.12.2 + || ==9.14.1 source-repository head type: git @@ -151,6 +151,7 @@ Library Data.Vector.Fixed.Storable Other-modules: Data.Vector.Fixed.Internal + Data.Vector.Fixed.Compat Test-Suite fixed-vector-doctests Default-Language: Haskell2010 From 18bc5d73630d7fc502e00a1d5f46089187b4ac37 Mon Sep 17 00:00:00 2001 From: Alexey Khudyakov Date: Thu, 22 Jan 2026 10:28:44 +0300 Subject: [PATCH 7/7] Add GHC 9.14 to CI Also add hack for 9.14. Aeson is not buildable with 9.14 yet. See: https://github.com/haskell/aeson/issues/1155 --- .github/workflows/ci.yml | 41 ++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d4d63f2..2b07bef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,12 +23,13 @@ jobs: matrix: include: # Linux - - { cabal: "3.14", os: ubuntu-latest, ghc: "9.2.8" } - - { cabal: "3.14", os: ubuntu-latest, ghc: "9.4.8" } - - { cabal: "3.14", os: ubuntu-latest, ghc: "9.6.7" } - - { cabal: "3.14", os: ubuntu-latest, ghc: "9.8.4" } - - { cabal: "3.14", os: ubuntu-latest, ghc: "9.10.2" } - - { cabal: "3.14", os: ubuntu-latest, ghc: "9.12.2" } + - { cabal: "3.16", os: ubuntu-latest, ghc: "9.2.8" } + - { cabal: "3.16", os: ubuntu-latest, ghc: "9.4.8" } + - { cabal: "3.16", os: ubuntu-latest, ghc: "9.6.7" } + - { cabal: "3.16", os: ubuntu-latest, ghc: "9.8.4" } + - { cabal: "3.16", os: ubuntu-latest, ghc: "9.10.2" } + - { cabal: "3.16", os: ubuntu-latest, ghc: "9.12.2" } + - { cabal: "3.16", os: ubuntu-latest, ghc: "9.14.1" } fail-fast: false steps: @@ -63,12 +64,36 @@ jobs: mkdir sdist for nm in fixed-vector*; do cabal sdist $nm -o sdist; done - name: Unpack + # NOTE: For time being aeson is not buildable with GHC9.14. + # See: https://github.com/haskell/aeson/issues/1155 + # NOTE: same for cborg + # See: https://github.com/well-typed/cborg/issues/373 run: | mkdir unpacked for nm in sdist/*; do tar -C unpacked -xf $nm; done cd unpacked - echo "packages: */*.cabal" > cabal.project - echo "tests: true" >> cabal.project + echo "packages:" > cabal.project + echo " fixed-vector-*/*.cabal" >> cabal.project + if [ {{ matrix.ghc }} != 9.14.1 ]; then + echo " fixed-vector-aeson-*/*.cabal" >> cabal.project; + else + rm -rf fixed-vector-aeson-* + fi + echo " fixed-vector-binary-*/*.cabal" >> cabal.project + if [ {{ matrix.ghc }} != 9.14.1 ]; then + echo " fixed-vector-cborg-*/*.cabal" >> cabal.project + else + rm -rf fixed-vector-cborg-* + fi + echo " fixed-vector-cereal-*/*.cabal" >> cabal.project + echo " fixed-vector-QC-*/*.cabal" >> cabal.project + if [ {{ matrix.ghc }} != 9.14.1 ]; then + echo " fixed-vector-test-*/*.cabal" >> cabal.project; + else + rm -rf fixed-vector-test-* + fi + echo "tests: true" >> cabal.project + cat cabal.project # ---------------- - name: cabal check run: |