1
1
{-# LANGUAGE CPP #-}
2
- {-# LANGUAGE DataKinds #-}
3
- {-# LANGUAGE KindSignatures #-}
4
- {-# LANGUAGE GADTs #-}
5
2
{-# LANGUAGE ScopedTypeVariables #-}
6
- {-# LANGUAGE TypeOperators #-}
7
3
{-# LANGUAGE TypeFamilies #-}
4
+ {-# LANGUAGE TypeOperators #-}
5
+ {-# LANGUAGE GeneralizedNewtypeDeriving #-}
6
+ {-# LANGUAGE DeriveTraversable #-}
7
+ {-# LANGUAGE DataKinds #-}
8
8
{-# LANGUAGE FlexibleContexts #-}
9
9
10
10
{-# OPTIONS_HADDOCK show-extensions #-}
@@ -27,6 +27,7 @@ This module defines fixed-length /vectors/ and some basic typeclass instances an
27
27
28
28
module Data.FixedSize.Vector
29
29
( Vector
30
+ , vZipWith
30
31
, (<%>)
31
32
, nil
32
33
, cons
@@ -45,61 +46,46 @@ module Data.FixedSize.Vector
45
46
import Data.FixedSize.Class
46
47
import Data.MyPrelude
47
48
import Data.Proxy
48
- import Data.Utils.Traversable
49
+ import Data.Utils.Traversable ( fromList )
49
50
import qualified Data.Vector as V
51
+ import qualified Data.Vector.Sized as VS
50
52
import GHC.TypeLits
51
- import GHC.TypeLits.Witnesses
52
53
53
54
-- | @'Vector' n a@ is the type of vectors of length @n@ with elements of type @a@.
54
- data Vector :: Nat -> * -> * where
55
-
56
- Vector :: KnownNat n => V. Vector a -> Vector n a
57
-
58
- instance Eq a => Eq (Vector n a ) where
59
-
60
- Vector xs == Vector ys = xs == ys
55
+ -- This is a simple wrapper around the 'VS.Vector' type from Joe Hermaszewski's
56
+ -- <https://hackage.haskell.org/package/vector-sized-0.3.3.0 vector-sized> library.
57
+ --
58
+ newtype Vector n a = Vector (VS. Vector n a )
59
+ deriving (Eq , Functor , Applicative , Foldable , Traversable , NFData )
61
60
62
61
instance Show a => Show (Vector n a ) where
63
62
64
- showsPrec p (Vector xs) = showsPrec p xs
65
-
66
- instance Functor (Vector n ) where
67
-
68
- fmap f (Vector v) = Vector (f <$> v)
69
-
70
- instance forall n . KnownNat n => Applicative (Vector n ) where
71
-
72
- pure x = let n = natVal (Proxy :: Proxy n ) in Vector (V. replicate (fromIntegral n) x)
73
-
74
- Vector fs <*> Vector xs = Vector (V. zipWith ($) fs xs)
75
-
76
- instance Foldable (Vector n ) where
77
-
78
- foldMap f (Vector xs) = foldMap f xs
79
-
80
- instance Traversable (Vector n ) where
81
-
82
- sequenceA (Vector xs) = Vector <$> sequenceA xs
63
+ show (Vector v) = show $ VS. fromSized v
83
64
84
65
instance (KnownNat n , Read a ) => Read (Vector n a ) where
85
66
86
- readsPrec p s = let xs = readsPrec p s :: [(V. Vector a , String )]
87
- n' = fromIntegral (natVal (Proxy :: Proxy n ))
88
- in [(Vector ys, t) | (ys, t) <- xs, length ys == n']
89
-
90
- instance (NFData a ) => NFData (Vector n a ) where
91
-
92
- rnf (Vector v) = rnf v
67
+ readsPrec p s = let xs = readsPrec p s
68
+ n' = fromIntegral (natVal (Proxy :: Proxy n ))
69
+ in [(Vector $ fromJust $ VS. toSized ys, t) | (ys, t) <- xs, length ys == n']
93
70
94
71
instance KnownNat n => FixedSize (Vector n ) where
95
72
96
73
type Index (Vector n ) = Int
97
74
98
75
type Size (Vector n ) = n
99
76
100
- Vector v !? i = v V. !? i
77
+ (Vector v) !? i = VS. fromSized v V. !? i
78
+
79
+ generate = Vector . VS. generate
101
80
102
- generate = Vector . V. generate (fromIntegral $ natVal (Proxy :: Proxy n ))
81
+ -- | Function @'vZipWith'@ zips two vectors of the same length, using the specified function.
82
+ --
83
+ -- >>> :set -XDataKinds
84
+ -- >>> let f = fromJust . fromList in vZipWith div (f [6,9]) (f [2,3]) :: Vector 2 Int
85
+ -- [3,3]
86
+ --
87
+ vZipWith :: (a -> b -> c ) -> Vector n a -> Vector n b -> Vector n c
88
+ vZipWith f (Vector v) (Vector w) = Vector $ VS. zipWith f v w
103
89
104
90
-- | The /scalar product/ of two vectors of the same length.
105
91
--
@@ -108,35 +94,35 @@ instance KnownNat n => FixedSize (Vector n) where
108
94
-- 11
109
95
--
110
96
(<%>) :: Num a => Vector n a -> Vector n a -> a
111
- Vector v <%> Vector w = V. sum $ V. zipWith (*) v w
97
+ v <%> w = sum $ vZipWith (*) v w
112
98
113
99
-- | The vector of length zero.
114
100
nil :: Vector 0 a
115
- nil = Vector V . empty
101
+ nil = Vector VS . empty
116
102
117
103
-- | Prepends the specified element to the specified vector.
118
104
--
119
105
-- >>> cons False (cons True nil)
120
106
-- [False,True]
121
107
--
122
108
cons :: forall a n . a -> Vector n a -> Vector (n + 1 ) a
123
- cons x (Vector xs) = withNatOp (%+) ( Proxy :: Proxy n ) ( Proxy :: Proxy 1 ) $ Vector $ V . cons x xs
109
+ cons x (Vector xs) = Vector $ VS . cons x xs
124
110
125
111
-- | Gets the first element of a vector of length greater than zero.
126
112
--
127
113
-- >>> vhead (cons 'x' (cons 'y' nil))
128
114
-- 'x'
129
115
--
130
- vhead :: ( 1 <= n ) => Vector n a -> a
131
- vhead (Vector v) = V .head v
116
+ vhead :: Vector ( n + 1 ) a -> a
117
+ vhead (Vector v) = VS .head v
132
118
133
119
-- | For a vector of length greater than zero, gets the vector with its first element removed.
134
120
--
135
121
-- >>> vtail (cons 'x' (cons 'y' nil))
136
122
-- "y"
137
123
--
138
- vtail :: forall a n . ( 1 <= n ) => Vector n a -> Vector ( n - 1 ) a
139
- vtail (Vector v) = withNatOp (%-) ( Proxy :: Proxy n ) ( Proxy :: Proxy 1 ) $ Vector ( V .tail v)
124
+ vtail :: forall a n . Vector ( n + 1 ) a -> Vector n a
125
+ vtail (Vector v) = Vector $ VS .tail v
140
126
141
127
infixl 6 <+>
142
128
@@ -146,8 +132,8 @@ infixl 6 <+>
146
132
-- >>> (cons 1 (cons 2 nil)) <+> (cons 3 (cons 4 nil)) :: Vector 2 Int
147
133
-- [4,6]
148
134
--
149
- (<+>) :: ( Num a , KnownNat n ) => Vector n a -> Vector n a -> Vector n a
150
- v <+> w = (+) <$> v <*> w
135
+ (<+>) :: Num a => Vector n a -> Vector n a -> Vector n a
136
+ ( <+>) = vZipWith (+)
151
137
152
138
infixl 6 <->
153
139
@@ -157,8 +143,8 @@ infixl 6 <->
157
143
-- >>> (cons 1 (cons 2 nil)) <-> (cons 3 (cons 4 nil)) :: Vector 2 Int
158
144
-- [-2,-2]
159
145
--
160
- (<->) :: ( Num a , KnownNat n ) => Vector n a -> Vector n a -> Vector n a
161
- v <-> w = (-) <$> v <*> w
146
+ (<->) :: Num a => Vector n a -> Vector n a -> Vector n a
147
+ ( <->) = vZipWith (-)
162
148
163
149
-- | Calculates the /squared/ euclidean norm of a vector,
164
150
-- i.e. the scalar product of the vector by itself.
@@ -182,7 +168,7 @@ sqDiff v w = sqNorm (v <-> w)
182
168
-- | Converts a fixed-size container to a 'Vector' of the same size.
183
169
--
184
170
toVector :: (FixedSize f , KnownNat (Size f )) => f a -> Vector (Size f ) a
185
- toVector = Vector . V . fromList . toList
171
+ toVector = Vector . fromJust . VS . fromList . toList
186
172
187
173
-- | Converts a 'Vector' to an arbitrary fixed-size container of the same size.
188
174
--
0 commit comments