string-isos-0.1.0.0: src/Text/Isomorphic.hs
{-# 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)