@@ -32,7 +32,15 @@ module Data.Syntax.Combinator
3232 vec,
3333 vecSepBy,
3434 ivec,
35− ivecSepBy
35+ ivecSepBy,
36+
37+ -- * Unboxed vectors.
38+ uvecNSepBy,
39+ uivecNSepBy,
40+ uvec,
41+ uvecSepBy,
42+ uivec,
43+ uivecSepBy
3644 ) where
3745
3846import Control.Category
@@ -41,8 +49,8 @@ import Control.Lens
4149import Control.Lens.SemiIso
4250import Control.SIArrow
4351import Data.Syntax
44−import Data.Vector (Vector)
4552import qualified Data.Vector as V
53+import qualified Data.Vector.Unboxed as VU
4654import Prelude hiding (id, (.))
4755
4856-- | One or zero occurences of @f@.
@@ -84,14 +92,14 @@ sepBy1 v s = _Cons /$/ v /*/ (s */ sepBy1 v s /+/ sipure _Empty)
8492-- | Constant size vector with separators.
8593--
8694-- @vecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
87−vecNSepBy :: Syntax syn => Int -> syn () a -> syn () () -> syn () (Vector a)
95+vecNSepBy :: Syntax syn => Int -> syn () a -> syn () () -> syn () (V.Vector a)
8896vecNSepBy n e sep = ivecNSepBy n (unit ^>> second e) sep
8997
9098-- | Constant size vector with separators and index-aware elements.
9199--
92100-- @ivecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
93101-- Each element gets its index and should output a value and the index unchanged.
94−ivecNSepBy :: Syntax syn => Int -> syn Int (Int, a) -> syn () () -> syn () (Vector a)
102+ivecNSepBy :: Syntax syn => Int -> syn Int (Int, a) -> syn () () -> syn () (V.Vector a)
95103ivecNSepBy n e sep = ivecN n $ sibind $ iso el (el . fst)
96104 where
97105 el k | k < n - 1 = unit ^>> e *** sep >># unit
@@ -100,27 +108,74 @@ ivecNSepBy n e sep = ivecN n $ sibind $ iso el (el . fst)
100108-- | Runtime sized vector. The size can depend on the result of some computation.
101109--
102110-- @vec e@ describes a vector with elements @e@.
103−vec :: Syntax syn => syn () a -> syn Int (Vector a)
111+vec :: Syntax syn => syn () a -> syn Int (V.Vector a)
104112vec e = vecSepBy e (siarr id)
105113
106114-- | Runtime sized vector with separators. The size can depend on the result of some
107115-- computation.
108116--
109117-- @vecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
110−vecSepBy :: Syntax syn => syn () a -> syn () () -> syn Int (Vector a)
118+vecSepBy :: Syntax syn => syn () a -> syn () () -> syn Int (V.Vector a)
111119vecSepBy e sep = ivecSepBy (unit ^>> second e) sep
112120
113121-- | Runtime sized vector with index-aware elements. The size can depend on the result
114122-- of some computation.
115123--
116124-- @ivec e@ describes a vector with elements @e@.
117−ivec :: Syntax syn => syn Int (Int, a) -> syn Int (Vector a)
125+ivec :: Syntax syn => syn Int (Int, a) -> syn Int (V.Vector a)
118126ivec e = ivecSepBy e (siarr id)
119127
120128-- | Runtime sized vector with index-aware elements and separators. The size can depend
121129-- on the result of some computation.
122130--
123131-- @ivecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
124−ivecSepBy :: Syntax syn => syn Int (Int, a) -> syn () () -> syn Int (Vector a)
132+ivecSepBy :: Syntax syn => syn Int (Int, a) -> syn () () -> syn Int (V.Vector a)
125133ivecSepBy e sep = sibind $ iso (\n -> constant n #>> ivecNSepBy n e sep)
126134 (\v -> constant (V.length v) #>> ivecNSepBy (V.length v) e sep)
135+
136+-- | Constant size unboxed vector with separators.
137+--
138+-- @uvecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
139+uvecNSepBy :: (Syntax syn, VU.Unbox a) => Int -> syn () a -> syn () () -> syn () (VU.Vector a)
140+uvecNSepBy n e sep = uivecNSepBy n (unit ^>> second e) sep
141+
142+-- | Constant size unboxed vector with separators and index-aware elements.
143+--
144+-- @uivecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
145+-- Each element gets its index and should output a value and the index unchanged.
146+uivecNSepBy :: (Syntax syn, VU.Unbox a) => Int -> syn Int (Int, a)
147+ -> syn () () -> syn () (VU.Vector a)
148+uivecNSepBy n e sep = uivecN n $ sibind $ iso el (el . fst)
149+ where
150+ el k | k < n - 1 = unit ^>> e *** sep >># unit
151+ | otherwise = e
152+
153+-- | Runtime sized unboxed vector. The size can depend on the result of some computation.
154+--
155+-- @uvec e@ describes a vector with elements @e@.
156+uvec :: (Syntax syn, VU.Unbox a) => syn () a -> syn Int (VU.Vector a)
157+uvec e = uvecSepBy e (siarr id)
158+
159+-- | Runtime sized unboxed vector with separators. The size can depend on the result of some
160+-- computation.
161+--
162+-- @uvecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
163+uvecSepBy :: (Syntax syn, VU.Unbox a) => syn () a -> syn () () -> syn Int (VU.Vector a)
164+uvecSepBy e sep = uivecSepBy (unit ^>> second e) sep
165+
166+-- | Runtime sized unboxed vector with index-aware elements. The size can depend on the result
167+-- of some computation.
168+--
169+-- @uivec e@ describes a vector with elements @e@.
170+uivec :: (Syntax syn, VU.Unbox a) => syn Int (Int, a) -> syn Int (VU.Vector a)
171+uivec e = uivecSepBy e (siarr id)
172+
173+-- | Runtime sized unboxed vector with index-aware elements and separators. The size can depend
174+-- on the result of some computation.
175+--
176+-- @uivecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
177+uivecSepBy :: (Syntax syn, VU.Unbox a) => syn Int (Int, a)
178+ -> syn () () -> syn Int (VU.Vector a)
179+uivecSepBy e sep = sibind $ iso (\n -> constant n #>> uivecNSepBy n e sep)
180+ (\v -> constant (VU.length v)
181+ #>> uivecNSepBy (VU.length v) e sep)