chunked-data (empty) → 0.1.0.0
raw patch · 8 files changed
+458/−0 lines, 8 filesdep +basedep +blaze-builderdep +bytestringsetup-changed
Dependencies added: base, blaze-builder, bytestring, containers, mono-traversable, semigroups, system-filepath, text, transformers, vector
Files
- Data/Builder.hs +88/−0
- Data/ChunkedZip.hs +172/−0
- Data/IOData.hs +88/−0
- Data/Sequences/Lazy.hs +28/−0
- Data/Textual/Encoding.hs +31/−0
- LICENSE +20/−0
- Setup.hs +2/−0
- chunked-data.cabal +29/−0
+ Data/Builder.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleContexts #-}+-- | Abstraction for different kinds of builders.+--+-- Note that whenever a character encoding is used, it will be UTF8. For+-- different behavior, please use the underlying library.+module Data.Builder+ ( TextBuilder+ , BlazeBuilder+ , Builder (..)+ , ToBuilder (..)+ , textToBuilder+ ) where++import Data.Monoid (Monoid)++import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.Builder as TB++import qualified Data.ByteString as S+import qualified Data.ByteString.Lazy as L+import qualified Blaze.ByteString.Builder as BB+import qualified Blaze.ByteString.Builder.Char.Utf8 as BB++-- | Since 0.1.0.0+type TextBuilder = TB.Builder++-- | Since 0.1.0.0+type BlazeBuilder = BB.Builder++-- | Since 0.1.0.0+class Monoid builder => Builder builder lazy | builder -> lazy, lazy -> builder where+ -- | Since 0.1.0.0+ builderToLazy :: builder -> lazy++ -- | Since 0.1.0.0+ flushBuilder :: builder++instance Builder TB.Builder TL.Text where+ builderToLazy = TB.toLazyText+ flushBuilder = TB.flush++instance Builder BB.Builder L.ByteString where+ builderToLazy = BB.toLazyByteString+ flushBuilder = BB.flush++-- | Since 0.1.0.0+class ToBuilder value builder where+ -- | Since 0.1.0.0+ toBuilder :: value -> builder++-- Text+instance ToBuilder TB.Builder TB.Builder where+ toBuilder = id+instance ToBuilder T.Text TB.Builder where+ toBuilder = TB.fromText+instance ToBuilder TL.Text TB.Builder where+ toBuilder = TB.fromLazyText+instance ToBuilder Char TB.Builder where+ toBuilder = TB.singleton+instance (a ~ Char) => ToBuilder [a] TB.Builder where+ toBuilder = TB.fromString++-- Blaze+instance ToBuilder BB.Builder BB.Builder where+ toBuilder = id+instance ToBuilder T.Text BB.Builder where+ toBuilder = BB.fromText+instance ToBuilder TL.Text BB.Builder where+ toBuilder = BB.fromLazyText+instance ToBuilder Char BB.Builder where+ toBuilder = BB.fromChar+instance (a ~ Char) => ToBuilder [a] BB.Builder where+ toBuilder = BB.fromString++instance ToBuilder S.ByteString BB.Builder where+ toBuilder = BB.fromByteString+instance ToBuilder L.ByteString BB.Builder where+ toBuilder = BB.fromLazyByteString++-- | Provided for type disambiguation in the presence of OverloadedStrings.+--+-- Since 0.1.0.0+textToBuilder :: ToBuilder T.Text builder => T.Text -> builder+textToBuilder = toBuilder
+ Data/ChunkedZip.hs view
@@ -0,0 +1,172 @@+-- | Various zipping and unzipping functions for chunked data structures.+module Data.ChunkedZip where++import Prelude hiding (zipWith, zipWith3)+import Control.Arrow ((&&&), (***))+import qualified Data.List as List+import qualified Data.List.NonEmpty as NonEmpty+import Data.List.NonEmpty (NonEmpty)+import qualified Data.Vector as Vector+-- import qualified Data.Vector.Unboxed as UVector+import qualified Data.Sequence as Seq+import Control.Monad.Trans.Identity+import Control.Monad.Trans.Reader+import qualified Data.IntMap as IntMap+import Data.Tree+import Data.Functor.Compose+import Data.Foldable (toList)++class Functor f => Zip f where+ zipWith :: (a -> b -> c) -> f a -> f b -> f c++ zip :: f a -> f b -> f (a, b)+ zip = zipWith (,)++ zap :: f (a -> b) -> f a -> f b+ zap = zipWith id++ unzip :: f (a, b) -> (f a, f b)+ unzip = fmap fst &&& fmap snd++instance Zip [] where+ zip = List.zip+ zipWith = List.zipWith+ unzip = List.unzip+instance Zip NonEmpty where+ zipWith = NonEmpty.zipWith+ zip = NonEmpty.zip+ unzip = NonEmpty.unzip+instance Zip Seq.Seq where+ zip = Seq.zip+ zipWith = Seq.zipWith+ unzip = (Seq.fromList *** Seq.fromList) . List.unzip . toList+instance Zip Tree where+ zipWith f (Node a as) (Node b bs) = Node (f a b) (zipWith (zipWith f) as bs)+instance Zip Vector.Vector where+ zip = Vector.zip+ unzip = Vector.unzip+ zipWith = Vector.zipWith+ {-+instance Zip UVector where+ zip = UVector.zip+ unzip = UVector.unzip+ zipWith = UVector.zipWith+ -}++instance Zip m => Zip (IdentityT m) where+ zipWith f (IdentityT m) (IdentityT n) = IdentityT (zipWith f m n)+instance Zip ((->)a) where+ zipWith f g h a = f (g a) (h a)+instance Zip m => Zip (ReaderT e m) where+ zipWith f (ReaderT m) (ReaderT n) = ReaderT $ \a ->+ zipWith f (m a) (n a)+instance Zip IntMap.IntMap where+ zipWith = IntMap.intersectionWith+instance (Zip f, Zip g) => Zip (Compose f g) where+ zipWith f (Compose a) (Compose b) = Compose $ zipWith (zipWith f) a b++class Functor f => Zip3 f where+ zipWith3 :: (a -> b -> c -> d) -> f a -> f b -> f c -> f d++ zip3 :: f a -> f b -> f c -> f (a, b, c)+ zip3 = zipWith3 (\x y z -> (x,y,z))++ zap3 :: f (a -> b -> c) -> f a -> f b -> f c+ zap3 = zipWith3 id++ unzip3 :: f (a, b, c) -> (f a, f b, f c)+ -- unzip3 = fmap (\(x,_,_)->x) &&& fmap (\(_,x,_)->x) &&& fmap (\(_,_,x)->x)++instance Zip3 [] where+ zip3 = List.zip3+ unzip3 = List.unzip3+ zipWith3 = List.zipWith3+instance Zip3 Vector.Vector where+ zip3 = Vector.zip3+ unzip3 = Vector.unzip3+ zipWith3 = Vector.zipWith3+instance Zip3 Seq.Seq where+ zip3 = Seq.zip3+ unzip3 = (\(a, b, c) -> (Seq.fromList a, Seq.fromList b, Seq.fromList c)) . List.unzip3 . toList+ zipWith3 = Seq.zipWith3++class Functor f => Zip4 f where+ zipWith4 :: (a -> b -> c -> d -> e) -> f a -> f b -> f c -> f d -> f e++ zip4 :: f a -> f b -> f c -> f d -> f (a, b, c, d)+ zip4 = zipWith4 (\w x y z -> (w, x,y,z))++ zap4 :: f (a -> b -> c -> d) -> f a -> f b -> f c -> f d+ zap4 = zipWith4 id++ unzip4 :: f (a, b, c, d) -> (f a, f b, f c, f d)++instance Zip4 [] where+ zip4 = List.zip4+ unzip4 = List.unzip4+ zipWith4 = List.zipWith4+instance Zip4 Vector.Vector where+ zip4 = Vector.zip4+ unzip4 = Vector.unzip4+ zipWith4 = Vector.zipWith4+instance Zip4 Seq.Seq where+ zip4 = Seq.zip4+ unzip4 = (\(a, b, c, d) -> (Seq.fromList a, Seq.fromList b, Seq.fromList c, Seq.fromList d)) . List.unzip4 . toList+ zipWith4 = Seq.zipWith4++class Functor f => Zip5 f where+ zipWith5 :: (a -> b -> c -> d -> e -> g) -> f a -> f b -> f c -> f d -> f e -> f g++ zip5 :: f a -> f b -> f c -> f d -> f e -> f (a, b, c, d, e)+ zip5 = zipWith5 (\v w x y z -> (v,w,x,y,z))++ zap5 :: f (a -> b -> c -> d -> e) -> f a -> f b -> f c -> f d -> f e+ zap5 = zipWith5 id++ unzip5 :: f (a, b, c, d, e) -> (f a, f b, f c, f d, f e)++instance Zip5 [] where+ zip5 = List.zip5+ unzip5 = List.unzip5+ zipWith5 = List.zipWith5+instance Zip5 Vector.Vector where+ zip5 = Vector.zip5+ unzip5 = Vector.unzip5+ zipWith5 = Vector.zipWith5++class Functor f => Zip6 f where+ zipWith6 :: (a -> b -> c -> d -> e -> g -> h) -> f a -> f b -> f c -> f d -> f e -> f g -> f h++ zip6 :: f a -> f b -> f c -> f d -> f e -> f g -> f (a, b, c, d, e, g)+ zip6 = zipWith6 (\u v w x y z -> (u, v,w,x,y,z))++ zap6 :: f (a -> b -> c -> d -> e -> g) -> f a -> f b -> f c -> f d -> f e -> f g+ zap6 = zipWith6 id++ unzip6 :: f (a, b, c, d, e, g) -> (f a, f b, f c, f d, f e, f g)++instance Zip6 [] where+ zip6 = List.zip6+ unzip6 = List.unzip6+ zipWith6 = List.zipWith6+instance Zip6 Vector.Vector where+ zip6 = Vector.zip6+ unzip6 = Vector.unzip6+ zipWith6 = Vector.zipWith6++class Functor f => Zip7 f where+ zipWith7 :: (a -> b -> c -> d -> e -> g -> h -> i) -> f a -> f b -> f c -> f d -> f e -> f g -> f h -> f i++ zip7 :: f a -> f b -> f c -> f d -> f e -> f g -> f h -> f (a, b, c, d, e, g, h)+ zip7 = zipWith7 (\t u v w x y z -> (t,u,v,w,x,y,z))++ zap7 :: f (a -> b -> c -> d -> e -> g -> h) -> f a -> f b -> f c -> f d -> f e -> f g -> f h+ zap7 = zipWith7 id++ unzip7 :: f (a, b, c, d, e, g, h) -> (f a, f b, f c, f d, f e, f g, f h)+ -- unzip3 = fmap (\(x,_,_)->x) &&& fmap (\(_,x,_)->x) &&& fmap (\(_,_,x)->x)++instance Zip7 [] where+ zip7 = List.zip7+ unzip7 = List.unzip7+ zipWith7 = List.zipWith7
+ Data/IOData.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE TypeFamilies #-}+module Data.IOData where++import Control.Monad (liftM)+import Control.Monad.IO.Class+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as ByteString8+import qualified Data.ByteString.Lazy as LByteString+import Data.ByteString.Lazy.Internal (defaultChunkSize)+import Data.Sequences (IsSequence)+import Data.Sequences.Lazy (fromStrict)+import qualified Data.Text as Text+import qualified Data.Text.IO as Text+import qualified Data.Text.Lazy as LText+import qualified Data.Text.Lazy.IO as LText+import Filesystem.Path (FilePath)+import qualified Filesystem.Path.CurrentOS as FilePath+import Prelude (Char, flip, ($), (.))+import qualified Prelude+import System.IO (Handle)+import qualified System.IO++-- | Data which can be read to and from files and handles.+--+-- Note that, for lazy sequences, these operations may perform+-- lazy I\/O.+class IsSequence a => IOData a where+ readFile :: MonadIO m => FilePath -> m a+ writeFile :: MonadIO m => FilePath -> a -> m ()+ getLine :: MonadIO m => m a+ hGetContents :: MonadIO m => Handle -> m a+ hGetLine :: MonadIO m => Handle -> m a+ hPut :: MonadIO m => Handle -> a -> m ()+ hPutStrLn :: MonadIO m => Handle -> a -> m ()+ hGetChunk :: MonadIO m => Handle -> m a+instance IOData ByteString.ByteString where+ readFile = liftIO . ByteString.readFile . FilePath.encodeString+ writeFile fp = liftIO . ByteString.writeFile (FilePath.encodeString fp)+ getLine = liftIO ByteString.getLine+ hGetContents = liftIO . ByteString.hGetContents+ hGetLine = liftIO . ByteString.hGetLine+ hPut h = liftIO . ByteString.hPut h+ hPutStrLn h = liftIO . ByteString8.hPutStrLn h+ hGetChunk = liftIO . flip ByteString.hGetSome defaultChunkSize+instance IOData LByteString.ByteString where+ readFile = liftIO . LByteString.readFile . FilePath.encodeString+ writeFile fp = liftIO . LByteString.writeFile (FilePath.encodeString fp)+ getLine = liftM fromStrict (liftIO ByteString.getLine)+ hGetContents = liftIO . LByteString.hGetContents+ hGetLine = liftM fromStrict . liftIO . ByteString.hGetLine+ hPut h = liftIO . LByteString.hPut h+ hPutStrLn h lbs = liftIO $ do+ LByteString.hPutStr h lbs+ ByteString8.hPutStrLn h ByteString.empty+ hGetChunk = liftM fromStrict . hGetChunk+instance IOData Text.Text where+ readFile = liftIO . Text.readFile . FilePath.encodeString+ writeFile fp = liftIO . Text.writeFile (FilePath.encodeString fp)+ getLine = liftIO Text.getLine+ hGetContents = liftIO . Text.hGetContents+ hGetLine = liftIO . Text.hGetLine+ hPut h = liftIO . Text.hPutStr h+ hPutStrLn h = liftIO . Text.hPutStrLn h+#if MIN_VERSION_text(0, 11, 3)+ hGetChunk = liftIO . Text.hGetChunk+#else+ -- Dangerously inefficient!+ hGetChunk = liftIO . liftM Text.singleton . System.IO.hGetChar+#endif+instance IOData LText.Text where+ readFile = liftIO . LText.readFile . FilePath.encodeString+ writeFile fp = liftIO . LText.writeFile (FilePath.encodeString fp)+ getLine = liftIO LText.getLine+ hGetContents = liftIO . LText.hGetContents+ hGetLine = liftIO . LText.hGetLine+ hPut h = liftIO . LText.hPutStr h+ hPutStrLn h = liftIO . LText.hPutStrLn h+ hGetChunk = liftM fromStrict . hGetChunk+instance (Char ~ c) => IOData [c] where+ readFile = liftIO . Prelude.readFile . FilePath.encodeString+ writeFile fp = liftIO . Prelude.writeFile (FilePath.encodeString fp)+ getLine = liftIO Prelude.getLine+ hGetContents = liftIO . System.IO.hGetContents+ hGetLine = liftIO . System.IO.hGetLine+ hPut h = liftIO . System.IO.hPutStr h+ hPutStrLn h = liftIO . System.IO.hPutStrLn h+ hGetChunk = liftM Text.unpack . hGetChunk
+ Data/Sequences/Lazy.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+module Data.Sequences.Lazy where++import qualified Data.ByteString as S+import qualified Data.ByteString.Lazy as L+import Data.Sequences+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL++-- | Lazy sequences containing strict chunks of data.+class (IsSequence lazy, IsSequence strict) => LazySequence lazy strict | lazy -> strict, strict -> lazy where+ toChunks :: lazy -> [strict]+ fromChunks :: [strict] -> lazy+ toStrict :: lazy -> strict+ fromStrict :: strict -> lazy++instance LazySequence L.ByteString S.ByteString where+ toChunks = L.toChunks+ fromChunks = L.fromChunks+ toStrict = S.concat . L.toChunks+ fromStrict = L.fromChunks . return++instance LazySequence TL.Text T.Text where+ toChunks = TL.toChunks+ fromChunks = TL.fromChunks+ toStrict = TL.toStrict+ fromStrict = TL.fromStrict
+ Data/Textual/Encoding.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+module Data.Textual.Encoding where++import qualified Data.ByteString as S+import qualified Data.ByteString.Lazy as L+import Data.Sequences+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import Data.Text.Encoding.Error (lenientDecode)+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.Encoding as TL+import Data.Word (Word8)++-- | Textual data which can be encoded to and decoded from UTF8.+class (Textual textual, IsSequence binary) => Utf8 textual binary | textual -> binary, binary -> textual where+ encodeUtf8 :: textual -> binary+ -- | Note that this function is required to be pure. In the case of+ -- a decoding error, Unicode replacement characters must be used.+ decodeUtf8 :: binary -> textual+instance (c ~ Char, w ~ Word8) => Utf8 [c] [w] where+ encodeUtf8 = L.unpack . TL.encodeUtf8 . TL.pack+ decodeUtf8 = TL.unpack . TL.decodeUtf8With lenientDecode . L.pack+instance Utf8 T.Text S.ByteString where+ encodeUtf8 = T.encodeUtf8+ decodeUtf8 = T.decodeUtf8With lenientDecode+instance Utf8 TL.Text L.ByteString where+ encodeUtf8 = TL.encodeUtf8+ decodeUtf8 = TL.decodeUtf8With lenientDecode
+ LICENSE view
@@ -0,0 +1,20 @@+The MIT License (MIT)++Copyright (c) 2014 FP Complete++Permission is hereby granted, free of charge, to any person obtaining a copy of+this software and associated documentation files (the "Software"), to deal in+the Software without restriction, including without limitation the rights to+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of+the Software, and to permit persons to whom the Software is furnished to do so,+subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ chunked-data.cabal view
@@ -0,0 +1,29 @@+name: chunked-data+version: 0.1.0.0+synopsis: Typeclasses for dealing with various chunked data representations+description: Originally present in classy-prelude.+homepage: https://github.com/fpco/chunked-data+license: MIT+license-file: LICENSE+author: Michael Snoyman+maintainer: michael@snoyman.com+category: Data+build-type: Simple+cabal-version: >=1.8++library+ exposed-modules: Data.IOData+ Data.Textual.Encoding+ Data.Sequences.Lazy+ Data.Builder+ Data.ChunkedZip+ build-depends: base >= 4 && < 5+ , transformers+ , bytestring+ , mono-traversable >=0.2+ , text >= 0.11+ , system-filepath+ , blaze-builder+ , containers+ , vector+ , semigroups