packages feed

string-isos (empty) → 0.1.0.0

raw patch · 6 files changed

+335/−0 lines, 6 filesdep +basedep +bytestringdep +mono-traversablesetup-changed

Dependencies added: base, bytestring, mono-traversable, safe, text, type-iso

Files

+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for string-isos++## 0.1.0.0  -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2018, Isaac Shapira++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Isaac Shapira nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Text/Foldable.hs view
@@ -0,0 +1,136 @@+{-# LANGUAGE DefaultSignatures    #-}+{-# LANGUAGE FlexibleInstances    #-}+{-# LANGUAGE TypeApplications     #-}+{-# LANGUAGE TypeFamilies         #-}+{-# LANGUAGE UndecidableInstances #-}++{-|+Many of the common things we want to do with String like structures are just properties of MonoFoldable.+This module provides a classes for MonoFoldables that contain Char as Stringlike structures.++The motivation here is to have re-usable functions abstracted over common things we get from Foldable.+The reason we can't just use the mono-traversable package, is that it's ByteString instances are MonoFoldables containing @Word8@, an the goal here is to normalize the API around Char.++For example:++@+  isFiveChars :: FoldableString s => s -> Bool+  isFiveChars s = length s == 5+@++Which will work with all 5 string types++The motivation here is to have re-usable functions abstracted over common things we get from Foldable.++For example:++@+  isFiveChars :: FoldableString s => s -> Bool+  isFiveChars s = length s == 5+@++Which will work with all 5 string types.+.++-}++module Text.Foldable+  ( module Data.MonoTraversable+  , FunctorString (..)+  , FoldableString (..)+  , TraverseString (..)) where++import qualified Data.ByteString            as BS+import qualified Data.ByteString.Char8      as BSC+import qualified Data.ByteString.Lazy       as BL+import qualified Data.ByteString.Lazy.Char8 as BLC+import qualified Data.Char                  as C+import           Data.MonoTraversable+import qualified Data.String                as S+import qualified Data.Text                  as TS+import qualified Data.Text.Encoding         as TSE+import qualified Data.Text.Lazy             as TL+import qualified Data.Text.Lazy.Encoding    as TLE++import           Text.Isomorphic++{-| MonoFunctor containing Char -}+class FunctorString s where+  map :: (Char -> Char) -> s -> s+  default map :: (MonoFunctor s, Element s ~ Char) => (Char -> Char) -> s -> s+  map = omap++instance FunctorString String+instance FunctorString TS.Text+instance FunctorString TL.Text+instance FunctorString BS.ByteString where map = BSC.map+instance FunctorString BL.ByteString where map = BLC.map++{-| MonoFoldable containing Char -}+class FoldableString s where+  foldMap :: (Char -> s) -> s -> s+  default foldMap :: (MonoFoldable s, Element s ~ Char, Monoid m) => (Char -> m) -> s -> m+  foldMap = ofoldMap+  foldr   :: (Char -> a -> a) -> a -> s -> a+  default foldr :: (MonoFoldable s, Element s ~ Char) => (Char -> a -> a) -> a -> s -> a+  foldr = ofoldr+  foldl'  :: (a -> Char -> a) -> a -> s -> a+  default foldl' :: (MonoFoldable s, Element s ~ Char) => (a -> Char -> a) -> a -> s -> a+  foldl' = ofoldl'+  all     :: (Char -> Bool) -> s -> Bool+  default all :: (MonoFoldable s, Element s ~ Char) => (Char -> Bool) -> s -> Bool+  all = oall+  any     :: (Char -> Bool) -> s -> Bool+  default any :: (MonoFoldable s, Element s ~ Char) => (Char -> Bool) -> s -> Bool+  any = oany+  null    :: s -> Bool+  default null :: (MonoFoldable s) => s -> Bool+  null = onull+  length  :: s -> Int+  default length :: (MonoFoldable s) => s -> Int+  length = olength+  elem    :: Char -> s -> Bool+  default elem :: (MonoFoldable s, Element s ~ Char) => Char -> s -> Bool+  elem = oelem+  maximum :: s -> Char+  default maximum :: (MonoFoldable s, Element s ~ Char) => s -> Char+  maximum = maximumEx+  minimum :: s -> Char+  default minimum :: (MonoFoldable s, Element s ~ Char) => s -> Char+  minimum = minimumEx++instance FoldableString String+instance FoldableString TS.Text+instance FoldableString TL.Text+instance FoldableString BS.ByteString where+  foldMap = BSC.concatMap+  foldr   = BSC.foldr+  foldl'  = BSC.foldl'+  all     = BSC.all+  any     = BSC.any+  elem    = BSC.elem+  maximum = BSC.maximum+  minimum = BSC.minimum+instance FoldableString BL.ByteString where+  foldMap = BLC.concatMap+  foldr   = BLC.foldr+  foldl'  = BLC.foldl'+  all     = BLC.all+  any     = BLC.any+  elem    = BLC.elem+  maximum = BLC.maximum+  minimum = BLC.minimum++{-| MonoTraversable containing Char -}+class (FunctorString s, FoldableString s) => TraverseString s where+  traverse :: Applicative f => (Char -> f Char) -> s -> f s+  default traverse :: (MonoTraversable s, Element s ~ Char, Applicative f) => (Char -> f Char) -> s -> f s+  traverse = otraverse++instance TraverseString String+instance TraverseString TS.Text+instance TraverseString TL.Text+instance TraverseString BS.ByteString where+  traverse f = fmap to . Prelude.traverse f . (to @ BS.ByteString @ String)+instance TraverseString BL.ByteString where+  traverse f = fmap to . Prelude.traverse f . (to @ BL.ByteString @ String)
+ src/Text/Isomorphic.hs view
@@ -0,0 +1,127 @@+{-# LANGUAGE ExplicitForAll        #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeSynonymInstances  #-}+{-# LANGUAGE UndecidableInstances  #-}++{-| Assuming UTF8 encoding the following types are isomorphic++  - Data.ByteString.Lazy.ByteString+  - Data.ByteString.ByteString+  - Data.Text.Lazy.Text+  - Data.Text.Text+  - String++Yet working with them and converting is a pain!++This package exposes this 5 way isomorphism to make conversion easy.+-}+module Text.Isomorphic+  ( module Data.Types.Injective+  , module Data.Types.Isomorphic+  , as, as2, as3, as4 ) where++import qualified Data.ByteString            as BS+import qualified Data.ByteString.Char8      as BSC+import qualified Data.ByteString.Lazy       as BL+import qualified Data.ByteString.Lazy.Char8 as BLC+import qualified Data.Char                  as C+import qualified Data.String                as S+import qualified Data.Text                  as TS+import qualified Data.Text.Encoding         as TSE+import qualified Data.Text.Lazy             as TL+import qualified Data.Text.Lazy.Encoding    as TLE+import           Data.Types.Injective+import           Data.Types.Isomorphic++instance {-# OVERLAPPABLE #-} S.IsString s => Injective String s where to = S.fromString+++instance Injective BS.ByteString String where+  to = BSC.unpack+  {-# INLINE to #-}+instance Injective String BS.ByteString where+  to = BSC.pack+  {-# INLINE to #-}+instance Iso String BS.ByteString+instance Iso BS.ByteString String++instance Injective BL.ByteString String where+  to = BLC.unpack+  {-# INLINE to #-}+instance Injective String BL.ByteString where+  to = BLC.pack+  {-# INLINE to #-}+instance Iso String BL.ByteString+instance Iso BL.ByteString String++instance Injective TS.Text BS.ByteString where+  to = TSE.encodeUtf8+  {-# INLINE to #-}+instance Injective BS.ByteString TS.Text where+  to = TSE.decodeUtf8+  {-# INLINE to #-}+instance Iso TS.Text BS.ByteString+instance Iso BS.ByteString TS.Text++instance Injective TS.Text BL.ByteString where+  to = BL.fromStrict . to+  {-# INLINE to #-}+instance Injective BL.ByteString TS.Text where+  to = to . BL.toStrict+  {-# INLINE to #-}+instance Iso TS.Text BL.ByteString+instance Iso BL.ByteString TS.Text++instance Injective TL.Text BS.ByteString where+  to = BL.toStrict . to+  {-# INLINE to #-}+instance Injective BS.ByteString TL.Text where+  to = to . BL.fromStrict+  {-# INLINE to #-}+instance Iso TL.Text BS.ByteString+instance Iso BS.ByteString TL.Text++instance Injective TL.Text BL.ByteString where+  to = TLE.encodeUtf8+  {-# INLINE to #-}+instance Injective BL.ByteString TL.Text where+  to = TLE.decodeUtf8+  {-# INLINE to #-}+instance Iso TL.Text BL.ByteString+instance Iso BL.ByteString TL.Text++instance Injective BS.ByteString BL.ByteString where+  to = BL.fromStrict+  {-# INLINE to #-}+instance Injective BL.ByteString BS.ByteString where+  to = BL.toStrict+  {-# INLINE to #-}+instance Iso BS.ByteString BL.ByteString+instance Iso BL.ByteString BS.ByteString++{-| This is useful for any iso, but in the case of string like stuff.+    You can now work with a function from one string type, while not having to do+    any conversion.++@+  f :: ByteString -> ByteString+  a :: Text+  as f a :: Text+@+-}+as :: forall a b. (Iso a b, Iso b a) => (a -> a) -> b -> b+as f = from . f . to+{-# INLINABLE as #-}++{-| Like @liftA2@ -}+as2 :: forall a b. (Iso a b, Iso b a) => (a -> a -> a) -> b -> b -> b+as2 f x y = from $ f (to x) (to y)++{-| Like @liftA3@ -}+as3 :: forall a b. (Iso a b, Iso b a) => (a -> a -> a -> a) -> b -> b -> b -> b+as3 f x y z = from $ f (to x) (to y) (to z)++{-| Like @liftA4@ -}+as4 :: forall a b. (Iso a b, Iso b a) => (a -> a -> a -> a -> a) -> b -> b -> b -> b -> b+as4 f w x y z = from $ f (to w) (to x) (to y) (to z)
+ string-isos.cabal view
@@ -0,0 +1,35 @@+-- Initial string-isos.cabal generated by cabal init.  For further+-- documentation, see http://haskell.org/cabal/users-guide/++name:                string-isos+version:             0.1.0.0+synopsis:            Tools for working with isomorphisms of strings+description:         Haskell has 5 common string types, Text, Lazy Text, ByteString, Lazy ByteString, and String ([Char]). Assuming utf8 encoding, we can make the pain of these conflicts much less via polymorphism.+license:             BSD3+license-file:        LICENSE+author:              Isaac Shapira+maintainer:          fresheyeball@gmail.com+-- copyright:+category:            Text+build-type:          Simple+extra-source-files:  ChangeLog.md+cabal-version:       >=1.10++source-repository head+  type: git+  location: https://gitlab.com/fresheyeball/String-Iso.git++library+  exposed-modules: Text.Isomorphic+                   Text.Foldable+  -- other-modules:+  -- other-extensions:+  ghc-options:         -Wwarn+  build-depends:       base             >= 4.9    && < 4.10.2+                     , text             >= 1.2.2  && < 1.3+                     , bytestring       >= 0.10.8 && < 0.11+                     , mono-traversable >= 1.0.2  && < 1.1+                     , type-iso         >= 0.1.0  && < 0.2+                     , safe             >= 0.3.15 && < 0.4+  hs-source-dirs:      src+  default-language:    Haskell2010