on master help sign in
Add unboxed vectors.
501ca35Paweł Nowak
Data/Syntax.hs+30−3
@@ -30,7 +30,8 @@ import Control.Lens.SemiIso
30import Control.SIArrow
30import Control.SIArrow
31import Data.MonoTraversable
31import Data.MonoTraversable
32import Data.Sequences hiding (take, takeWhile, replicate)
32import 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
34
35
35-- | An isomorphism between a sequence and a list of its elements.
36-- | An isomorphism between a sequence and a list of its elements.
36packed :: IsSequence seq => Iso' seq [Element seq]
37packed :: IsSequence seq => Iso' seq [Element seq]
@@ -105,7 +106,7 @@ class ( SIArrow syn
105 -- @vecN n e@ describes a size @n@ vector with elements @e@.
106 -- @vecN n e@ describes a size @n@ vector with elements @e@.
106 --
107 --
107 -- Also see 'Data.Syntax.Combinator.vec'.
108 -- Also see 'Data.Syntax.Combinator.vec'.
108− vecN :: Int -> syn () a -> syn () (Vector a)
109+ vecN :: Int -> syn () a -> syn () (V.Vector a)
109 vecN n e = packed /$/ sireplicate n e
110 vecN n e = packed /$/ sireplicate n e
110
111
111 -- | Constant size vector with index-aware element. The default implementation
112 -- | Constant size vector with index-aware element. The default implementation
@@ -116,7 +117,7 @@ class ( SIArrow syn
116 -- gets its index and should output a value and the index unchanged.
117 -- gets its index and should output a value and the index unchanged.
117 --
118 --
118 -- Also see 'Data.Syntax.Combinator.ivec'.
119 -- 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)
120 ivecN n e = (packed /$/)
121 ivecN n e = (packed /$/)
121 $ sisequence
122 $ sisequence
122 $ map (\(i, e') -> constant i ^>> e'
123 $ map (\(i, e') -> constant i ^>> e'
@@ -124,6 +125,32 @@ class ( SIArrow syn
124 >># unit . swapped)
125 >># unit . swapped)
125 $ zip [0 .. n-1] (replicate n e)
126 $ zip [0 .. n-1] (replicate n e)
126
127
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+
127 {-# MINIMAL anyChar #-}
154 {-# MINIMAL anyChar #-}
128
155
129instance Syntax syn => Syntax (ReaderCT env syn) where
156instance Syntax syn => Syntax (ReaderCT env syn) where
Data/Syntax/Combinator.hs+63−8
@@ -32,7 +32,15 @@ module Data.Syntax.Combinator
32 vec,
32 vec,
33 vecSepBy,
33 vecSepBy,
34 ivec,
34 ivec,
35− ivecSepBy
35+ ivecSepBy,
36+
37+ -- * Unboxed vectors.
38+ uvecNSepBy,
39+ uivecNSepBy,
40+ uvec,
41+ uvecSepBy,
42+ uivec,
43+ uivecSepBy
36 ) where
44 ) where
37
45
38import Control.Category
46import Control.Category
@@ -41,8 +49,8 @@ import Control.Lens
41import Control.Lens.SemiIso
49import Control.Lens.SemiIso
42import Control.SIArrow
50import Control.SIArrow
43import Data.Syntax
51import Data.Syntax
44−import Data.Vector (Vector)
45import qualified Data.Vector as V
52import qualified Data.Vector as V
53+import qualified Data.Vector.Unboxed as VU
46import Prelude hiding (id, (.))
54import Prelude hiding (id, (.))
47
55
48-- | One or zero occurences of @f@.
56-- | One or zero occurences of @f@.
@@ -84,14 +92,14 @@ sepBy1 v s = _Cons /$/ v /*/ (s */ sepBy1 v s /+/ sipure _Empty)
84-- | Constant size vector with separators.
92-- | Constant size vector with separators.
85--
93--
86-- @vecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
94-- @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)
88vecNSepBy n e sep = ivecNSepBy n (unit ^>> second e) sep
96vecNSepBy n e sep = ivecNSepBy n (unit ^>> second e) sep
89
97
90-- | Constant size vector with separators and index-aware elements.
98-- | Constant size vector with separators and index-aware elements.
91--
99--
92-- @ivecNSepBy n e sep@ describes a size @n@ vector with elements @e@ separated by @sep@.
100-- @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.
101-- 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)
95ivecNSepBy n e sep = ivecN n $ sibind $ iso el (el . fst)
103ivecNSepBy n e sep = ivecN n $ sibind $ iso el (el . fst)
96 where
104 where
97 el k | k < n - 1 = unit ^>> e *** sep >># unit
105 el k | k < n - 1 = unit ^>> e *** sep >># unit
@@ -100,27 +108,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.
108-- | Runtime sized vector. The size can depend on the result of some computation.
101--
109--
102-- @vec e@ describes a vector with elements @e@.
110-- @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)
104vec e = vecSepBy e (siarr id)
112vec e = vecSepBy e (siarr id)
105
113
106-- | Runtime sized vector with separators. The size can depend on the result of some
114-- | Runtime sized vector with separators. The size can depend on the result of some
107-- computation.
115-- computation.
108--
116--
109-- @vecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
117-- @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)
111vecSepBy e sep = ivecSepBy (unit ^>> second e) sep
119vecSepBy e sep = ivecSepBy (unit ^>> second e) sep
112
120
113-- | Runtime sized vector with index-aware elements. The size can depend on the result
121-- | Runtime sized vector with index-aware elements. The size can depend on the result
114-- of some computation.
122-- of some computation.
115--
123--
116-- @ivec e@ describes a vector with elements @e@.
124-- @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)
118ivec e = ivecSepBy e (siarr id)
126ivec e = ivecSepBy e (siarr id)
119
127
120-- | Runtime sized vector with index-aware elements and separators. The size can depend
128-- | Runtime sized vector with index-aware elements and separators. The size can depend
121-- on the result of some computation.
129-- on the result of some computation.
122--
130--
123-- @ivecSepBy e sep@ describes a vector with elements @e@ separated by @sep@.
131-- @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)
125ivecSepBy e sep = sibind $ iso (\n -> constant n #>> ivecNSepBy n e sep)
133ivecSepBy e sep = sibind $ iso (\n -> constant n #>> ivecNSepBy n e sep)
126 (\v -> constant (V.length v) #>> ivecNSepBy (V.length v) e sep)
134 (\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)