@@ -26,13 +26,24 @@ module Data.Syntax.Combinator
29+ -- * Arrowized combinators.
29 -- * Vectors.
32 -- * Vectors.
30 vecNSepBy,
33 vecNSepBy,
31 ivecNSepBy,
34 ivecNSepBy,
35− ivecSepBy
38+ ivecSepBy,
40+ -- * Unboxed vectors.
38import Control.Category
49import Control.Category
@@ -40,10 +51,11 @@ import Control.Category.Structures
40import Control.Lens
51import Control.Lens
41import Control.Lens.SemiIso
52import Control.Lens.SemiIso
42import Control.SIArrow
53import Control.SIArrow
54+import qualified Data.MonoTraversable as Seq
43import Data.Syntax
55import Data.Syntax
44−import Data.Vector (Vector)
45import qualified Data.Vector as V
56import qualified Data.Vector as V
57+import qualified Data.Vector.Unboxed as VU
46−import Prelude hiding (id, (.))
58+import Prelude hiding (id, (.), take)
48-- | One or zero occurences of @f@.
60-- | One or zero occurences of @f@.
49optional :: SIArrow cat => cat () a -> cat () (Maybe a)
61optional :: SIArrow cat => cat () a -> cat () (Maybe a)
@@ -81,17 +93,22 @@ sepBy v s = sepBy1 v s /+/ sipure _Empty
81sepBy1 :: SIArrow cat => cat () a -> cat () () -> cat () [a]
93sepBy1 :: SIArrow cat => cat () a -> cat () () -> cat () [a]
82sepBy1 v s = _Cons /$/ v /*/ (s */ sepBy1 v s /+/ sipure _Empty)
94sepBy1 v s = _Cons /$/ v /*/ (s */ sepBy1 v s /+/ sipure _Empty)
96+-- | A string of given length.
97+takeArr :: Syntax syn => syn Int (Seq syn)
98+takeArr = sibind $ iso (\n -> constant n #>> take n)
99+ (\s -> constant (Seq.olength s) #>> take (Seq.olength s))
84-- | Constant size vector with separators.
101-- | Constant size vector with separators.
86-- @vecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
103-- @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)
104+vecNSepBy :: Syntax syn => Int -> syn () a -> syn () () -> syn () (V.Vector a)
88vecNSepBy n e sep = ivecNSepBy n (unit ^>> second e) sep
105vecNSepBy n e sep = ivecNSepBy n (unit ^>> second e) sep
90-- | Constant size vector with separators and index-aware elements.
107-- | Constant size vector with separators and index-aware elements.
92-- @ivecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
109-- @ivecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
93-- Each element gets its index and should output a value and the index unchanged.
110-- 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)
111+ivecNSepBy :: Syntax syn => Int -> syn Int (Int, a) -> syn () () -> syn () (V.Vector a)
95ivecNSepBy n e sep = ivecN n $ sibind $ iso el (el . fst)
112ivecNSepBy n e sep = ivecN n $ sibind $ iso el (el . fst)
97 el k | k < n - 1 = unit ^>> e *** sep >># unit
114 el k | k < n - 1 = unit ^>> e *** sep >># unit
@@ -100,27 +117,74 @@ ivecNSepBy n e sep = ivecN n $ sibind $ iso el (el . fst)
100-- | Runtime sized vector. The size can depend on the result of some computation.
117-- | Runtime sized vector. The size can depend on the result of some computation.
102-- @vec e@ describes a vector with elements @e@.
119-- @vec e@ describes a vector with elements @e@.
103−vec :: Syntax syn => syn () a -> syn Int (Vector a)
120+vec :: Syntax syn => syn () a -> syn Int (V.Vector a)
104vec e = vecSepBy e (siarr id)
121vec e = vecSepBy e (siarr id)
106-- | Runtime sized vector with separators. The size can depend on the result of some
123-- | Runtime sized vector with separators. The size can depend on the result of some
107-- computation.
124-- computation.
109-- @vecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
126-- @vecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
110−vecSepBy :: Syntax syn => syn () a -> syn () () -> syn Int (Vector a)
127+vecSepBy :: Syntax syn => syn () a -> syn () () -> syn Int (V.Vector a)
111vecSepBy e sep = ivecSepBy (unit ^>> second e) sep
128vecSepBy e sep = ivecSepBy (unit ^>> second e) sep
113-- | Runtime sized vector with index-aware elements. The size can depend on the result
130-- | Runtime sized vector with index-aware elements. The size can depend on the result
114-- of some computation.
131-- of some computation.
116-- @ivec e@ describes a vector with elements @e@.
133-- @ivec e@ describes a vector with elements @e@.
117−ivec :: Syntax syn => syn Int (Int, a) -> syn Int (Vector a)
134+ivec :: Syntax syn => syn Int (Int, a) -> syn Int (V.Vector a)
118ivec e = ivecSepBy e (siarr id)
135ivec e = ivecSepBy e (siarr id)
120-- | Runtime sized vector with index-aware elements and separators. The size can depend
137-- | Runtime sized vector with index-aware elements and separators. The size can depend
121-- on the result of some computation.
138-- on the result of some computation.
123-- @ivecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
140-- @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)
141+ivecSepBy :: Syntax syn => syn Int (Int, a) -> syn () () -> syn Int (V.Vector a)
125ivecSepBy e sep = sibind $ iso (\n -> constant n #>> ivecNSepBy n e sep)
142ivecSepBy e sep = sibind $ iso (\n -> constant n #>> ivecNSepBy n e sep)
126 (\v -> constant (V.length v) #>> ivecNSepBy (V.length v) e sep)
143 (\v -> constant (V.length v) #>> ivecNSepBy (V.length v) e sep)
145+-- | Constant size unboxed vector with separators.
147+-- @uvecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
148+uvecNSepBy :: (Syntax syn, VU.Unbox a) => Int -> syn () a -> syn () () -> syn () (VU.Vector a)
149+uvecNSepBy n e sep = uivecNSepBy n (unit ^>> second e) sep
151+-- | Constant size unboxed vector with separators and index-aware elements.
153+-- @uivecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
154+-- Each element gets its index and should output a value and the index unchanged.
155+uivecNSepBy :: (Syntax syn, VU.Unbox a) => Int -> syn Int (Int, a)
156+ -> syn () () -> syn () (VU.Vector a)
157+uivecNSepBy n e sep = uivecN n $ sibind $ iso el (el . fst)
159+ el k | k < n - 1 = unit ^>> e *** sep >># unit
162+-- | Runtime sized unboxed vector. The size can depend on the result of some computation.
164+-- @uvec e@ describes a vector with elements @e@.
165+uvec :: (Syntax syn, VU.Unbox a) => syn () a -> syn Int (VU.Vector a)
166+uvec e = uvecSepBy e (siarr id)
168+-- | Runtime sized unboxed vector with separators. The size can depend on the result of some
171+-- @uvecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
172+uvecSepBy :: (Syntax syn, VU.Unbox a) => syn () a -> syn () () -> syn Int (VU.Vector a)
173+uvecSepBy e sep = uivecSepBy (unit ^>> second e) sep
175+-- | Runtime sized unboxed vector with index-aware elements. The size can depend on the result
176+-- of some computation.
178+-- @uivec e@ describes a vector with elements @e@.
179+uivec :: (Syntax syn, VU.Unbox a) => syn Int (Int, a) -> syn Int (VU.Vector a)
180+uivec e = uivecSepBy e (siarr id)
182+-- | Runtime sized unboxed vector with index-aware elements and separators. The size can depend
183+-- on the result of some computation.
185+-- @uivecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
186+uivecSepBy :: (Syntax syn, VU.Unbox a) => syn Int (Int, a)
187+ -> syn () () -> syn Int (VU.Vector a)
188+uivecSepBy e sep = sibind $ iso (\n -> constant n #>> uivecNSepBy n e sep)
189+ (\v -> constant (VU.length v)
190+ #>> uivecNSepBy (VU.length v) e sep)