deferred-folds 0.9.12 → 0.9.13
raw patch · 5 files changed
+91/−1 lines, 5 filesdep +textPVP ok
version bump matches the API change (PVP)
Dependencies added: text
API changes (from Hackage documentation)
+ DeferredFolds.Unfoldr: textChars :: Text -> Unfoldr Char
+ DeferredFolds.Unfoldr: textWords :: Text -> Unfoldr Text
Files
- deferred-folds.cabal +3/−1
- library/DeferredFolds/Defs/Unfoldr.hs +45/−0
- library/DeferredFolds/Prelude.hs +4/−0
- library/DeferredFolds/Util/TextArray.hs +30/−0
- test/Main.hs +9/−0
deferred-folds.cabal view
@@ -1,5 +1,5 @@ name: deferred-folds-version: 0.9.12+version: 0.9.13 category: Folding synopsis: Abstractions over deferred folds description:@@ -36,6 +36,7 @@ DeferredFolds.Defs.Unfoldr DeferredFolds.Defs.UnfoldrM DeferredFolds.Prelude+ DeferredFolds.Util.TextArray build-depends: base >=4.9 && <5, bytestring >=0.10 && <0.12,@@ -43,6 +44,7 @@ foldl >=1 && <2, hashable >=1 && <2, primitive >=0.6.4 && <0.8,+ text >=1.2 && <1.3, transformers >=0.5 && <0.6, unordered-containers >=0.2 && <0.3, vector >=0.12 && <0.13
library/DeferredFolds/Defs/Unfoldr.hs view
@@ -9,6 +9,8 @@ import qualified Data.ByteString as ByteString import qualified Data.ByteString.Short.Internal as ShortByteString import qualified Data.Vector.Generic as GenericVector+import qualified Data.Text.Internal as TextInternal+import qualified DeferredFolds.Util.TextArray as TextArrayUtil deriving instance Functor Unfoldr@@ -342,3 +344,46 @@ else step sep (step a (next False))) (const init) True++{-|+Reproduces the behaviour of 'Data.Text.unpack'.++Implementation is efficient and avoids allocation of an intermediate list.+-}+textChars :: Text -> Unfoldr Char+textChars (TextInternal.Text arr off len) =+ Unfoldr $ \ step term ->+ let+ loop !offset =+ if offset >= len+ then term+ else + TextArrayUtil.iter arr offset $ \ char nextOffset ->+ step char (loop nextOffset)+ in loop off++{-|+Reproduces the behaviour of 'Data.Text.words'.++Implementation is efficient and avoids allocation of an intermediate list.+-}+textWords :: Text -> Unfoldr Text+textWords (TextInternal.Text arr off len) =+ Unfoldr $ \ step term ->+ let+ loop !wordOffset !offset =+ if offset >= len+ then if wordOffset == offset+ then term+ else step (chunk wordOffset offset) term+ else+ TextArrayUtil.iter arr offset $ \ char nextOffset ->+ if isSpace char+ then if wordOffset == offset+ then loop nextOffset nextOffset+ else step (chunk wordOffset offset) (loop nextOffset nextOffset)+ else loop wordOffset nextOffset+ in loop off off+ where+ chunk startOffset afterEndOffset =+ TextInternal.Text arr startOffset (afterEndOffset - startOffset)
library/DeferredFolds/Prelude.hs view
@@ -103,3 +103,7 @@ -- hashable ------------------------- import Data.Hashable as Exports (Hashable)++-- text+-------------------------+import Data.Text as Exports (Text)
+ library/DeferredFolds/Util/TextArray.hs view
@@ -0,0 +1,30 @@+module DeferredFolds.Util.TextArray+where++import DeferredFolds.Prelude+import qualified Data.Text.Internal as TextInternal+import qualified Data.Text.Internal.Encoding.Utf16 as TextUtf16+import qualified Data.Text.Internal.Unsafe.Char as TextChar+import qualified Data.Text.Array as TextArray+++{-|+Same as 'Data.Text.Unsafe.iter',+but operates on the array directly,+uses a continuation and passes the next offset to it instead of delta.+-}+{-# INLINE iter #-}+iter :: TextArray.Array -> Int -> (Char -> Int -> a) -> a+iter arr offset cont =+ let+ b1 =+ TextArray.unsafeIndex arr offset+ in if b1 >= 0xd800 && b1 <= 0xdbff+ then let+ b2 =+ TextArray.unsafeIndex arr (succ offset)+ char =+ TextUtf16.chr2 b1 b2+ in cont char (offset + 2)+ else+ cont (TextChar.unsafeChr b1) (offset + 1)
test/Main.hs view
@@ -9,6 +9,7 @@ import qualified Test.QuickCheck as QuickCheck import qualified Test.QuickCheck.Property as QuickCheck import qualified DeferredFolds.Unfoldr as Unfoldr+import qualified Data.Text as Text main =@@ -28,4 +29,12 @@ testProperty "intersperse" $ \ (list :: [Char]) -> intersperse ',' list === toList (Unfoldr.intersperse ',' (Unfoldr.foldable list))+ ,+ testProperty "textChars" $ \ (text :: Text) ->+ Text.unpack text ===+ toList (Unfoldr.textChars text)+ ,+ testProperty "textWords" $ \ (text :: Text) ->+ Text.words text ===+ toList (Unfoldr.textWords text) ]