on master help sign in
Add unboxed vectors.
commit501ca351783eac92b36f9e07d12508722dfdad96 authorPaweł Nowak <pawel834@gmail.com> dateFri 12 Dec 2014, 19:41 (12 years ago) parentb6dbe1a
2 files changed+93−11
Data/Syntax.hs+30−3 Data/Syntax/Combinator.hs+63−8
Data/Syntax.hs+30−3
@@ -30,7 +30,8 @@ import Control.Lens.SemiIso
3030import Control.SIArrow
3131import Data.MonoTraversable
3232import Data.Sequences hiding (take, takeWhile, replicate)
33−import Data.Vector (Vector)
33+import qualified Data.Vector as V
34+import qualified Data.Vector.Unboxed as VU
3435
3536-- | An isomorphism between a sequence and a list of its elements.
3637packed :: IsSequence seq => Iso' seq [Element seq]
@@ -105,7 +106,7 @@ class ( SIArrow syn
105106 -- @vecN n e@ describes a size @n@ vector with elements @e@.
106107 --
107108 -- Also see 'Data.Syntax.Combinator.vec'.
108− vecN :: Int -> syn () a -> syn () (Vector a)
109+ vecN :: Int -> syn () a -> syn () (V.Vector a)
109110 vecN n e = packed /$/ sireplicate n e
110111
111112 -- | Constant size vector with index-aware element. The default implementation
@@ -116,7 +117,7 @@ class ( SIArrow syn
116117 -- gets its index and should output a value and the index unchanged.
117118 --
118119 -- Also see 'Data.Syntax.Combinator.ivec'.
119− ivecN :: Int -> syn Int (Int, a) -> syn () (Vector a)
120+ ivecN :: Int -> syn Int (Int, a) -> syn () (V.Vector a)
120121 ivecN n e = (packed /$/)
121122 $ sisequence
122123 $ map (\(i, e') -> constant i ^>> e'
@@ -124,6 +125,32 @@ class ( SIArrow syn
124125 >># unit . swapped)
125126 $ zip [0 .. n-1] (replicate n e)
126127
128+ -- | Constant size unboxed vector. The default implementation uses lists, but
129+ -- "syntax-attoparsec" and "syntax-printer" override it with an efficient
130+ -- implementation that works on a vector directly.
131+ --
132+ -- @vecN n e@ describes a size @n@ vector with elements @e@.
133+ --
134+ -- Also see 'Data.Syntax.Combinator.vec'.
135+ uvecN :: VU.Unbox a => Int -> syn () a -> syn () (VU.Vector a)
136+ uvecN n e = packed /$/ sireplicate n e
137+
138+ -- | Constant size unboxed vector with index-aware element. The default implementation
139+ -- uses lists, but "syntax-attoparsec" and "syntax-printer" override it with an
140+ -- efficient implementation that works on a vector directly.
141+ --
142+ -- @ivecN n e@ describes a size @n@ vector with elements @e@. Each element
143+ -- gets its index and should output a value and the index unchanged.
144+ --
145+ -- Also see 'Data.Syntax.Combinator.ivec'.
146+ uivecN :: VU.Unbox a => Int -> syn Int (Int, a) -> syn () (VU.Vector a)
147+ uivecN n e = (packed /$/)
148+ $ sisequence
149+ $ map (\(i, e') -> constant i ^>> e'
150+ >>> first (sipure (constant i))
151+ >># unit . swapped)
152+ $ zip [0 .. n-1] (replicate n e)
153+
127154 {-# MINIMAL anyChar #-}
128155
129156instance Syntax syn => Syntax (ReaderCT env syn) where
Data/Syntax/Combinator.hs+63−8
@@ -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)