isomorphism-class-0.1.0.10/0000755000000000000000000000000007346545000013574 5ustar0000000000000000isomorphism-class-0.1.0.10/LICENSE0000644000000000000000000000204107346545000014576 0ustar0000000000000000Copyright (c) 2022 Nikita Volkov 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. isomorphism-class-0.1.0.10/isomorphism-class.cabal0000644000000000000000000000337707346545000020246 0ustar0000000000000000cabal-version: 3.0 name: isomorphism-class version: 0.1.0.10 synopsis: Isomorphism typeclass solving the conversion problem homepage: https://github.com/nikita-volkov/isomorphism-class bug-reports: https://github.com/nikita-volkov/isomorphism-class/issues author: Nikita Volkov maintainer: Nikita Volkov copyright: (c) 2022 Nikita Volkov license: MIT license-file: LICENSE source-repository head type: git location: git://github.com/nikita-volkov/isomorphism-class.git common language-settings default-language: Haskell2010 default-extensions: NoImplicitPrelude FlexibleContexts FlexibleInstances MagicHash MultiParamTypeClasses ScopedTypeVariables TypeApplications UndecidableSuperClasses library import: language-settings hs-source-dirs: library exposed-modules: IsomorphismClass other-modules: IsomorphismClass.Prelude IsomorphismClass.TextCompat.Array build-depends: , base >=4.12 && <5 , bytestring >=0.10 && <0.12 , containers >=0.6 && <0.7 , hashable >=1 && <2 , primitive >=0.7.3 && <0.10 , text >=1.2 && <3 , unordered-containers >=0.2 && <0.3 , vector >=0.12 && <0.14 test-suite test import: language-settings type: exitcode-stdio-1.0 hs-source-dirs: test main-is: Main.hs other-modules: Test.ExtraInstances build-depends: , bytestring >=0.10 && <0.12 , isomorphism-class , primitive >=0.7.3 && <0.10 , QuickCheck >=2.13 && <3 , quickcheck-instances >=0.3.28 && <0.4 , rebase >=1.15 && <2 , tasty >=1.2.3 && <2 , tasty-quickcheck >=0.10.1 && <0.11 , text >=1.2 && <3 , vector >=0.12 && <0.14 isomorphism-class-0.1.0.10/library/0000755000000000000000000000000007346545000015240 5ustar0000000000000000isomorphism-class-0.1.0.10/library/IsomorphismClass.hs0000644000000000000000000004310307346545000021074 0ustar0000000000000000{-# OPTIONS_GHC -Wno-unused-top-binds #-} -- | -- Isomorphism as a lawful solution to the conversion problem. -- -- = Conversion problem -- -- Have you ever looked for a @toString@ function? How often do you -- import @Data.Text.Lazy@ only to call its 'Data.Text.Lazy.fromStrict'? How -- about importing @Data.Text@ only to call its 'Data.Text.unpack'? How -- about going thru the always fun sequence of -- importing @Data.ByteString.Builder@ only to call its -- 'Data.ByteString.Builder.toLazyByteString' and then importing -- @Data.ByteString.Lazy@ only to call its 'Data.ByteString.Lazy.toStrict'? -- -- Those all are instances of one pattern. They are conversions between -- representations of the same information. Codebases that don't attempt to -- abstract over this pattern tend to be sprawling with this type of -- boilerplate. It's noise to the codereader, it's a burden to the -- implementor and the maintainer. -- -- = Why another conversion library? -- -- Many libraries exist that approach the conversion problem. However all of -- them provide lawless typeclasses leaving it up to the author of the -- instance to define what makes a proper conversion. This results in -- inconsistencies across instances and their behaviour being not evident to -- the user. -- -- This library tackles this problem with a lawful typeclass, making it -- evident what any of its instances do. -- -- = The law -- -- The key insight of this library is that if you add a requirement for the -- conversion to be lossless and to have a mirror conversion in the opposite -- direction, there usually appears to be only one way of defining it. That -- makes it very clear what the conversion does to the user and how to define -- it to the author of the conversion. -- -- That insight itself stems from an observation that almost all of the -- practical conversions in Haskell share a property: you can restore the -- original data from its converted form. E.g., you can get a bytestring from -- a builder and you can create a builder from a bytestring, you can convert -- a text into a list of chars and vice-versa, bytestring to\/from bytearray, -- strict bytestring to\/from lazy, list to\/from sequence, sequence to/from -- vector, set of ints to\/from int-set. In other words, it's always a two-way -- street with them and there's a lot of instances of this pattern. -- -- = UX -- -- A few other accidental findings like encoding this property with recursive -- typeclass constraints and fine-tuning for the use of -- the @TypeApplications@ extension resulted in a very terse yet clear API. -- -- Essentially the whole API is just two functions: 'to' and 'from'. Both -- perform a conversion between two types. The only difference between them -- is in what the first type application parameter specifies. E.g.: -- -- > fromString = from @String -- -- > toText = to @Text -- -- In other words 'to' and 'from' let you explicitly specify either the source -- or the target type of a conversion when you need to help the type -- inferencer. -- -- Here are more practical examples: -- -- @ -- renderNameAndHeight :: 'Text' -> 'Int' -> 'Text' -- renderNameAndHeight name height = -- 'from' @'TextLazyBuilder.Builder' $ -- "Height of " <> 'to' name <> " is " <> 'showAs' height -- @ -- -- @ -- combineEncodings :: 'ByteStringShort.ShortByteString' -> 'PrimitiveByteArray.ByteArray' -> 'ByteString' -> [Word8] -- combineEncodings a b c = -- 'from' @'ByteStringBuilder.Builder' $ -- 'to' a <> 'to' b <> 'to' c -- @ module IsomorphismClass ( -- * Typeclass IsomorphicTo (..), from, -- * Common Utilities showAs, -- * FAQ -- | -- = Why no instance for Text/ByteString? -- -- It is not a total isomorphism. Yes, you can represent every Text value using ByteString. -- However, not every ByteString can be decoded as valid Text. -- It doesn't matter which encoding you apply: UTF8, ISO-8859 or any other. -- -- = String/Text is not exactly a valid isomorphism -- -- Yes. It does not make a valid isomorphism. It is an exception, -- due to the ubiquity of String-oriented APIs. -- -- = Are Int64/Word64 really isomorphic? -- -- Yes. Negative integer values get mapped to the upper value range of Word64. -- Mapping between those types happens in bits using the 'fromIntegral' function. ) where import qualified Data.ByteString as ByteString import qualified Data.ByteString.Builder as ByteStringBuilder import qualified Data.ByteString.Lazy as ByteStringLazy import qualified Data.ByteString.Short as ByteStringShort import qualified Data.ByteString.Short.Internal as ByteStringShortInternal import qualified Data.Primitive.ByteArray as PrimitiveByteArray import qualified Data.Sequence as Seq import qualified Data.Text as Text import qualified Data.Text.Array as TextArray import qualified Data.Text.Lazy as TextLazy import qualified Data.Text.Lazy.Builder as TextLazyBuilder import qualified Data.Vector as Vector import IsomorphismClass.Prelude import qualified IsomorphismClass.TextCompat.Array as TextCompatArray -- | Bidirectional conversion between two types with no loss of information. -- The bidirectionality is encoded via a recursive dependency with arguments -- flipped. -- -- You can read the signature @IsomorphicTo a b@ as \"/B/ is isomorphic to /A/\". -- -- __Laws__ -- -- /B/ is isomorphic to /A/ if and only if there exists a conversion from /B/ -- to /A/ ('to') and a conversion from /A/ to /B/ ('from') such that: -- -- - @'from' . 'to' = 'id'@ - For all values of /B/ converting from /B/ to /A/ -- and then converting from /A/ to /B/ produces a value that is identical -- to the original. -- -- - @'to' . 'from' = 'id'@ - For all values of /A/ converting from /A/ to /B/ -- and then converting from /B/ to /A/ produces a value that is identical -- to the original. -- -- __Usage__ -- -- This class is particularly easy to use in combination with -- the @TypeApplications@ extension making it clear to the reader what sort -- of conversion he sees. E.g., -- -- > fromString = from @String -- -- > toText = to @Text -- -- The types are also self-evident: -- -- > > :t from @String -- > from @String :: IsomorphicTo b String => String -> b -- -- > > :t to @Text -- > to @Text :: IsomorphicTo Text b => b -> Text -- -- __Instance Definition__ -- -- For each pair of isomorphic types (/A/ and /B/) the compiler will require -- you to define two instances, namely: @IsomorphicTo A B@ and @IsomorphicTo -- B A@. class (IsomorphicTo b a) => IsomorphicTo a b where to :: b -> a -- instance IsomorphicTo String Text where to = Text.unpack instance IsomorphicTo String TextLazy.Text where to = TextLazy.unpack instance IsomorphicTo String TextLazyBuilder.Builder where to = TextLazy.unpack . TextLazyBuilder.toLazyText -- instance IsomorphicTo [Word8] ByteString where to = ByteString.unpack instance IsomorphicTo [Word8] ByteStringLazy.ByteString where to = ByteStringLazy.unpack instance IsomorphicTo [Word8] ByteStringShort.ShortByteString where to = ByteStringShort.unpack instance IsomorphicTo [Word8] ByteStringBuilder.Builder where to = ByteStringLazy.unpack . ByteStringBuilder.toLazyByteString instance IsomorphicTo [Word8] PrimitiveByteArray.ByteArray where to = toList instance IsomorphicTo [Word8] TextArray.Array where to = to . to @ByteStringShort.ShortByteString -- instance IsomorphicTo [a] [a] where to = id instance IsomorphicTo [a] (Vector a) where to = toList instance IsomorphicTo [a] (Seq a) where to = toList -- instance IsomorphicTo Text Text where to = id -- | Performs replacement on invalid Unicode chars in the string. instance IsomorphicTo Text String where to = Text.pack instance IsomorphicTo Text TextLazy.Text where to = TextLazy.toStrict instance IsomorphicTo Text TextLazyBuilder.Builder where to = TextLazy.toStrict . TextLazyBuilder.toLazyText -- instance IsomorphicTo TextLazy.Text TextLazy.Text where to = id -- | Performs replacement on invalid Unicode chars in the string. instance IsomorphicTo TextLazy.Text String where to = TextLazy.pack instance IsomorphicTo TextLazy.Text Text where to = TextLazy.fromStrict instance IsomorphicTo TextLazy.Text TextLazyBuilder.Builder where to = TextLazyBuilder.toLazyText -- instance IsomorphicTo TextLazyBuilder.Builder TextLazyBuilder.Builder where to = id -- | Performs replacement on invalid Unicode chars in the string. instance IsomorphicTo TextLazyBuilder.Builder String where to = TextLazyBuilder.fromString instance IsomorphicTo TextLazyBuilder.Builder Text where to = TextLazyBuilder.fromText instance IsomorphicTo TextLazyBuilder.Builder TextLazy.Text where to = TextLazyBuilder.fromLazyText -- instance IsomorphicTo ByteString ByteString where to = id instance IsomorphicTo ByteString [Word8] where to = ByteString.pack instance IsomorphicTo ByteString ByteStringLazy.ByteString where to = ByteStringLazy.toStrict instance IsomorphicTo ByteString ByteStringShort.ShortByteString where to = ByteStringShort.fromShort instance IsomorphicTo ByteString ByteStringBuilder.Builder where to = ByteStringLazy.toStrict . ByteStringBuilder.toLazyByteString instance IsomorphicTo ByteString PrimitiveByteArray.ByteArray where to = to . to @ByteStringShort.ShortByteString instance IsomorphicTo ByteString TextArray.Array where to = to . to @ByteStringShort.ShortByteString -- instance IsomorphicTo ByteStringLazy.ByteString ByteStringLazy.ByteString where to = id instance IsomorphicTo ByteStringLazy.ByteString [Word8] where to = ByteStringLazy.pack instance IsomorphicTo ByteStringLazy.ByteString ByteString where to = ByteStringLazy.fromStrict instance IsomorphicTo ByteStringLazy.ByteString ByteStringShort.ShortByteString where to = from @ByteString . to instance IsomorphicTo ByteStringLazy.ByteString ByteStringBuilder.Builder where to = ByteStringBuilder.toLazyByteString instance IsomorphicTo ByteStringLazy.ByteString PrimitiveByteArray.ByteArray where to = to . to @ByteStringShort.ShortByteString instance IsomorphicTo ByteStringLazy.ByteString TextArray.Array where to = to . to @ByteStringShort.ShortByteString -- instance IsomorphicTo ByteStringShort.ShortByteString ByteStringShort.ShortByteString where to = id instance IsomorphicTo ByteStringShort.ShortByteString [Word8] where to = ByteStringShort.pack instance IsomorphicTo ByteStringShort.ShortByteString ByteString where to = ByteStringShort.toShort instance IsomorphicTo ByteStringShort.ShortByteString ByteStringLazy.ByteString where to = to . to @ByteString instance IsomorphicTo ByteStringShort.ShortByteString ByteStringBuilder.Builder where to = to . to @ByteStringLazy.ByteString instance IsomorphicTo ByteStringShort.ShortByteString PrimitiveByteArray.ByteArray where to (PrimitiveByteArray.ByteArray array) = ByteStringShortInternal.SBS array instance IsomorphicTo ByteStringShort.ShortByteString TextArray.Array where to a = ByteStringShortInternal.SBS (TextCompatArray.toUnliftedByteArray a) -- instance IsomorphicTo ByteStringBuilder.Builder ByteStringBuilder.Builder where to = id instance IsomorphicTo ByteStringBuilder.Builder [Word8] where to = to . to @ByteString instance IsomorphicTo ByteStringBuilder.Builder ByteString where to = ByteStringBuilder.byteString instance IsomorphicTo ByteStringBuilder.Builder ByteStringLazy.ByteString where to = ByteStringBuilder.lazyByteString instance IsomorphicTo ByteStringBuilder.Builder ByteStringShort.ShortByteString where to = ByteStringBuilder.shortByteString instance IsomorphicTo ByteStringBuilder.Builder PrimitiveByteArray.ByteArray where to = to . to @ByteStringShort.ShortByteString instance IsomorphicTo ByteStringBuilder.Builder TextArray.Array where to = to . to @ByteStringShort.ShortByteString -- instance IsomorphicTo PrimitiveByteArray.ByteArray PrimitiveByteArray.ByteArray where to = id instance IsomorphicTo PrimitiveByteArray.ByteArray [Word8] where to = fromList instance IsomorphicTo PrimitiveByteArray.ByteArray ByteStringShort.ShortByteString where to (ByteStringShortInternal.SBS array) = PrimitiveByteArray.ByteArray array instance IsomorphicTo PrimitiveByteArray.ByteArray ByteString where to = to . to @ByteStringShort.ShortByteString instance IsomorphicTo PrimitiveByteArray.ByteArray ByteStringLazy.ByteString where to = to . to @ByteStringShort.ShortByteString instance IsomorphicTo PrimitiveByteArray.ByteArray ByteStringBuilder.Builder where to = to . to @ByteStringShort.ShortByteString instance IsomorphicTo PrimitiveByteArray.ByteArray TextArray.Array where to a = PrimitiveByteArray.ByteArray (TextCompatArray.toUnliftedByteArray a) -- instance IsomorphicTo TextArray.Array [Word8] where to = to . to @ByteStringShort.ShortByteString instance IsomorphicTo TextArray.Array PrimitiveByteArray.ByteArray where to (PrimitiveByteArray.ByteArray arr) = TextCompatArray.fromUnliftedByteArray arr instance IsomorphicTo TextArray.Array ByteStringShort.ShortByteString where to (ByteStringShortInternal.SBS arr) = TextCompatArray.fromUnliftedByteArray arr instance IsomorphicTo TextArray.Array ByteString where to = to . to @ByteStringShort.ShortByteString instance IsomorphicTo TextArray.Array ByteStringLazy.ByteString where to = to . to @ByteStringShort.ShortByteString instance IsomorphicTo TextArray.Array ByteStringBuilder.Builder where to = to . to @ByteStringShort.ShortByteString -- instance IsomorphicTo (Vector a) (Vector a) where to = id instance IsomorphicTo (Vector a) [a] where to = Vector.fromList instance IsomorphicTo (Vector a) (Seq a) where to = from @[a] . to -- instance IsomorphicTo (Seq a) (Seq a) where to = id instance IsomorphicTo (Seq a) [a] where to = Seq.fromList instance IsomorphicTo (Seq a) (Vector a) where to = from @[a] . to -- instance IsomorphicTo (Set a) (Set a) where to = id instance IsomorphicTo (Set Int) IntSet where to = fromList . toList -- instance IsomorphicTo IntSet IntSet where to = id instance IsomorphicTo IntSet (Set Int) where to = fromList . toList -- instance IsomorphicTo (Map k v) (Map k v) where to = id instance IsomorphicTo (Map Int v) (IntMap v) where to = fromList . toList -- instance IsomorphicTo (IntMap a) (IntMap a) where to = id instance IsomorphicTo (IntMap v) (Map Int v) where to = fromList . toList -- instance IsomorphicTo (Maybe a) (Maybe a) where to = id instance IsomorphicTo (Either a b) (Either a b) where to = id instance IsomorphicTo (First a) (First a) where to = id instance IsomorphicTo (Last a) (Last a) where to = id instance IsomorphicTo (Product a) (Product a) where to = id instance IsomorphicTo (Sum a) (Sum a) where to = id -- instance IsomorphicTo Bool Bool where to = id instance IsomorphicTo Char Char where to = id instance IsomorphicTo Double Double where to = id instance IsomorphicTo Float Float where to = id instance IsomorphicTo Int Int where to = id instance IsomorphicTo Int Word where to = fromIntegral instance IsomorphicTo Int16 Int16 where to = id instance IsomorphicTo Int16 Word16 where to = fromIntegral instance IsomorphicTo Int32 Int32 where to = id instance IsomorphicTo Int32 Word32 where to = fromIntegral instance IsomorphicTo Int64 Int64 where to = id instance IsomorphicTo Int64 Word64 where to = fromIntegral instance IsomorphicTo Int8 Int8 where to = id instance IsomorphicTo Int8 Word8 where to = fromIntegral instance IsomorphicTo Integer Integer where to = id instance IsomorphicTo Rational Rational where to = id instance IsomorphicTo Word Int where to = fromIntegral instance IsomorphicTo Word Word where to = id instance IsomorphicTo Word16 Int16 where to = fromIntegral instance IsomorphicTo Word16 Word16 where to = id instance IsomorphicTo Word32 Int32 where to = fromIntegral instance IsomorphicTo Word32 Word32 where to = id instance IsomorphicTo Word64 Int64 where to = fromIntegral instance IsomorphicTo Word64 Word64 where to = id instance IsomorphicTo Word8 Int8 where to = fromIntegral instance IsomorphicTo Word8 Word8 where to = id -- -- | -- 'to' in reverse direction. -- -- Particularly useful in combination with the @TypeApplications@ extension, -- where it allows to specify the input type, e.g.: -- -- > fromString :: IsomorphicTo a String => String -> a -- > fromString = from @String -- -- The first type application of the 'to' function on the other hand specifies -- the output data type. from :: forall a b. (IsomorphicTo b a) => a -> b from = to -- | -- Ideally there should be a direct instance and this function -- should merely serve as a helper for defining instances -- by merely composing from other instances. -- -- E.g., -- -- > thru @String Proxy -- -- captures the following pattern: -- -- > from @String . to -- -- However it is advised to use the conversion functions directly, -- since it makes the intent clearer and is actually shorter. {-# INLINE thru #-} thru :: (IsomorphicTo a b, IsomorphicTo a c) => Proxy a -> b -> c thru proxy = from . flip asProxyTypeOf proxy . to {-# INLINE thruString #-} thruString :: (IsomorphicTo String a, IsomorphicTo String b) => a -> b thruString = from @String . to {-# INLINE thruText #-} thruText :: (IsomorphicTo Text a, IsomorphicTo Text b) => a -> b thruText = from @Text . to {-# INLINE thruList #-} thruList :: forall a f g. (IsomorphicTo [a] (f a), IsomorphicTo [a] (g a)) => f a -> g a thruList = from @[a] . to -- | A utility, which uses the 'Show' instance to produce a value -- that is isomorphic to 'String'. -- -- It lets you generalize over the functions like the following: -- -- > showAsText :: Show a => a -> Text -- > showAsText = showAs @Text -- -- > showAsBuilder :: Show a => a -> Builder -- > showAsBuilder = showAs @Builder showAs :: forall b a. (IsomorphicTo String b, Show a) => a -> b showAs = from . show isomorphism-class-0.1.0.10/library/IsomorphismClass/0000755000000000000000000000000007346545000020537 5ustar0000000000000000isomorphism-class-0.1.0.10/library/IsomorphismClass/Prelude.hs0000644000000000000000000000672307346545000022503 0ustar0000000000000000module IsomorphismClass.Prelude ( module Exports, ) where import Control.Applicative as Exports import Control.Arrow as Exports hiding (first, second) import Control.Category as Exports import Control.Concurrent as Exports import Control.Exception as Exports import Control.Monad as Exports hiding (fail, forM, forM_, mapM, mapM_, msum, sequence, sequence_) import Control.Monad.Fail as Exports import Control.Monad.Fix as Exports hiding (fix) import Control.Monad.IO.Class as Exports import Control.Monad.ST as Exports import Data.Bifunctor as Exports import Data.Bits as Exports import Data.Bool as Exports import Data.ByteString as Exports (ByteString) import Data.Char as Exports import Data.Coerce as Exports import Data.Complex as Exports import Data.Data as Exports import Data.Dynamic as Exports import Data.Either as Exports import Data.Fixed as Exports import Data.Foldable as Exports hiding (toList) import Data.Function as Exports hiding (id, (.)) import Data.Functor as Exports import Data.Functor.Classes as Exports import Data.Functor.Compose as Exports import Data.Functor.Contravariant as Exports import Data.Functor.Identity as Exports import Data.HashMap.Strict as Exports (HashMap) import Data.HashSet as Exports (HashSet) import Data.Hashable as Exports import Data.IORef as Exports import Data.Int as Exports import Data.IntMap.Strict as Exports (IntMap) import Data.IntSet as Exports (IntSet) import Data.Ix as Exports import Data.List as Exports hiding (all, and, any, concat, concatMap, elem, find, foldl, foldl', foldl1, foldr, foldr1, mapAccumL, mapAccumR, maximum, maximumBy, minimum, minimumBy, notElem, or, product, sum) import Data.List.NonEmpty as Exports (NonEmpty (..)) import Data.Map.Strict as Exports (Map) import Data.Maybe as Exports import Data.Monoid as Exports hiding (First (..), Last (..), (<>)) import Data.Ord as Exports import Data.Proxy as Exports import Data.Ratio as Exports import Data.STRef as Exports import Data.Semigroup as Exports import Data.Sequence as Exports (Seq) import Data.Set as Exports (Set) import Data.String as Exports import Data.Text as Exports (Text) import Data.Traversable as Exports import Data.Tuple as Exports import Data.Unique as Exports import Data.Vector as Exports (Vector) import Data.Version as Exports import Data.Void as Exports import Data.Word as Exports import Debug.Trace as Exports import Foreign.ForeignPtr as Exports import Foreign.Ptr as Exports import Foreign.StablePtr as Exports import Foreign.Storable as Exports import GHC.Conc as Exports hiding (orElse, threadWaitRead, threadWaitReadSTM, threadWaitWrite, threadWaitWriteSTM, withMVar) import GHC.Exts as Exports (IsList (..), groupWith, inline, lazy, sortWith) import GHC.Generics as Exports (Generic, Generic1) import GHC.IO.Exception as Exports import GHC.OverloadedLabels as Exports import GHC.Records as Exports import Numeric as Exports import Numeric.Natural as Exports import System.Environment as Exports import System.Exit as Exports import System.IO as Exports import System.IO.Error as Exports import System.IO.Unsafe as Exports import System.Mem as Exports import System.Mem.StableName as Exports import System.Timeout as Exports import Text.Printf as Exports (hPrintf, printf) import Text.Read as Exports (Read (..), readEither, readMaybe) import Unsafe.Coerce as Exports import Prelude as Exports hiding (all, and, any, concat, concatMap, elem, fail, foldl, foldl1, foldr, foldr1, id, mapM, mapM_, maximum, minimum, notElem, or, product, sequence, sequence_, sum, (.)) isomorphism-class-0.1.0.10/library/IsomorphismClass/TextCompat/0000755000000000000000000000000007346545000022627 5ustar0000000000000000isomorphism-class-0.1.0.10/library/IsomorphismClass/TextCompat/Array.hs0000644000000000000000000000076607346545000024252 0ustar0000000000000000{-# LANGUAGE CPP #-} module IsomorphismClass.TextCompat.Array where import Data.Text.Array import GHC.Exts (ByteArray#) {-# INLINE toUnliftedByteArray #-} toUnliftedByteArray :: Array -> ByteArray# #if MIN_VERSION_text(2,0,0) toUnliftedByteArray (ByteArray a) = a #else toUnliftedByteArray (Array a) = a #endif {-# INLINE fromUnliftedByteArray #-} fromUnliftedByteArray :: ByteArray# -> Array #if MIN_VERSION_text(2,0,0) fromUnliftedByteArray = ByteArray #else fromUnliftedByteArray = Array #endif isomorphism-class-0.1.0.10/test/0000755000000000000000000000000007346545000014553 5ustar0000000000000000isomorphism-class-0.1.0.10/test/Main.hs0000644000000000000000000001510407346545000015774 0ustar0000000000000000module Main where import qualified Data.ByteString.Builder as ByteStringBuilder import qualified Data.ByteString.Lazy as ByteStringLazy import qualified Data.ByteString.Short as ByteStringShort import qualified Data.Primitive.ByteArray as PrimitiveByteArray import qualified Data.Text.Lazy as TextLazy import qualified Data.Text.Lazy.Builder as TextLazyBuilder import IsomorphismClass import Rebase.Prelude import Test.ExtraInstances () import Test.Tasty import Test.Tasty.QuickCheck hiding ((.&.)) main :: IO () main = defaultMain allTests allTests :: TestTree allTests = testGroup "All" $ [ testPair @String @Text Proxy Proxy, testPair @String @TextLazy.Text Proxy Proxy, testPair @String @TextLazyBuilder.Builder Proxy Proxy, testPair @[Word8] @ByteString Proxy Proxy, testPair @[Word8] @ByteStringLazy.ByteString Proxy Proxy, testPair @[Word8] @ByteStringShort.ShortByteString Proxy Proxy, testPair @[Word8] @ByteStringBuilder.Builder Proxy Proxy, testPair @[Word8] @PrimitiveByteArray.ByteArray Proxy Proxy, testPair @[Word8] @[Word8] Proxy Proxy, testPair @[Word8] @(Vector Word8) Proxy Proxy, testPair @[Word8] @(Seq Word8) Proxy Proxy, testPair @Text @Text Proxy Proxy, testPair @Text @String Proxy Proxy, testPair @Text @TextLazy.Text Proxy Proxy, testPair @Text @TextLazyBuilder.Builder Proxy Proxy, testPair @TextLazy.Text @TextLazy.Text Proxy Proxy, testPair @TextLazy.Text @String Proxy Proxy, testPair @TextLazy.Text @Text Proxy Proxy, testPair @TextLazy.Text @TextLazyBuilder.Builder Proxy Proxy, testPair @TextLazyBuilder.Builder @TextLazyBuilder.Builder Proxy Proxy, testPair @TextLazyBuilder.Builder @String Proxy Proxy, testPair @TextLazyBuilder.Builder @Text Proxy Proxy, testPair @TextLazyBuilder.Builder @TextLazy.Text Proxy Proxy, testPair @ByteString @ByteString Proxy Proxy, testPair @ByteString @[Word8] Proxy Proxy, testPair @ByteString @ByteStringLazy.ByteString Proxy Proxy, testPair @ByteString @ByteStringShort.ShortByteString Proxy Proxy, testPair @ByteString @ByteStringBuilder.Builder Proxy Proxy, testPair @ByteString @PrimitiveByteArray.ByteArray Proxy Proxy, testPair @ByteStringLazy.ByteString @ByteStringLazy.ByteString Proxy Proxy, testPair @ByteStringLazy.ByteString @[Word8] Proxy Proxy, testPair @ByteStringLazy.ByteString @ByteString Proxy Proxy, testPair @ByteStringLazy.ByteString @ByteStringShort.ShortByteString Proxy Proxy, testPair @ByteStringLazy.ByteString @ByteStringBuilder.Builder Proxy Proxy, testPair @ByteStringLazy.ByteString @PrimitiveByteArray.ByteArray Proxy Proxy, testPair @ByteStringShort.ShortByteString @ByteStringShort.ShortByteString Proxy Proxy, testPair @ByteStringShort.ShortByteString @[Word8] Proxy Proxy, testPair @ByteStringShort.ShortByteString @ByteString Proxy Proxy, testPair @ByteStringShort.ShortByteString @ByteStringLazy.ByteString Proxy Proxy, testPair @ByteStringShort.ShortByteString @ByteStringBuilder.Builder Proxy Proxy, testPair @ByteStringShort.ShortByteString @PrimitiveByteArray.ByteArray Proxy Proxy, testPair @ByteStringBuilder.Builder @ByteStringBuilder.Builder Proxy Proxy, testPair @ByteStringBuilder.Builder @[Word8] Proxy Proxy, testPair @ByteStringBuilder.Builder @ByteString Proxy Proxy, testPair @ByteStringBuilder.Builder @ByteStringLazy.ByteString Proxy Proxy, testPair @ByteStringBuilder.Builder @ByteStringShort.ShortByteString Proxy Proxy, testPair @ByteStringBuilder.Builder @PrimitiveByteArray.ByteArray Proxy Proxy, testPair @PrimitiveByteArray.ByteArray @PrimitiveByteArray.ByteArray Proxy Proxy, testPair @PrimitiveByteArray.ByteArray @[Word8] Proxy Proxy, testPair @PrimitiveByteArray.ByteArray @ByteStringShort.ShortByteString Proxy Proxy, testPair @PrimitiveByteArray.ByteArray @ByteString Proxy Proxy, testPair @PrimitiveByteArray.ByteArray @ByteStringLazy.ByteString Proxy Proxy, testPair @PrimitiveByteArray.ByteArray @ByteStringBuilder.Builder Proxy Proxy, testPair @(Vector Word8) @(Vector Word8) Proxy Proxy, testPair @(Vector Word8) @[Word8] Proxy Proxy, testPair @(Vector Word8) @(Seq Word8) Proxy Proxy, testPair @(Seq Word8) @(Seq Word8) Proxy Proxy, testPair @(Seq Word8) @[Word8] Proxy Proxy, testPair @(Seq Word8) @(Vector Word8) Proxy Proxy, testPair @(Set Word8) @(Set Word8) Proxy Proxy, testPair @(Set Int) @IntSet Proxy Proxy, testPair @IntSet @IntSet Proxy Proxy, testPair @IntSet @(Set Int) Proxy Proxy, testPair @(Map Word8 Word8) @(Map Word8 Word8) Proxy Proxy, testPair @(Map Int Word8) @(IntMap Word8) Proxy Proxy, testPair @(IntMap Word8) @(IntMap Word8) Proxy Proxy, testPair @(IntMap Word8) @(Map Int Word8) Proxy Proxy, testPair @(Maybe Word8) @(Maybe Word8) Proxy Proxy, testPair @(Either Word8 Word8) @(Either Word8 Word8) Proxy Proxy, testPair @(First Word8) @(First Word8) Proxy Proxy, testPair @(Last Word8) @(Last Word8) Proxy Proxy, testPair @(Product Word8) @(Product Word8) Proxy Proxy, testPair @(Sum Word8) @(Sum Word8) Proxy Proxy, testPair @Bool @Bool Proxy Proxy, testPair @Char @Char Proxy Proxy, testPair @Double @Double Proxy Proxy, testPair @Float @Float Proxy Proxy, testPair @Int @Int Proxy Proxy, testPair @Int @Word Proxy Proxy, testPair @Int16 @Int16 Proxy Proxy, testPair @Int16 @Word16 Proxy Proxy, testPair @Int32 @Int32 Proxy Proxy, testPair @Int32 @Word32 Proxy Proxy, testPair @Int64 @Int64 Proxy Proxy, testPair @Int64 @Word64 Proxy Proxy, testPair @Int8 @Int8 Proxy Proxy, testPair @Int8 @Word8 Proxy Proxy, testPair @Integer @Integer Proxy Proxy, testPair @Rational @Rational Proxy Proxy, testPair @Word @Int Proxy Proxy, testPair @Word @Word Proxy Proxy, testPair @Word16 @Int16 Proxy Proxy, testPair @Word16 @Word16 Proxy Proxy, testPair @Word32 @Int32 Proxy Proxy, testPair @Word32 @Word32 Proxy Proxy, testPair @Word64 @Int64 Proxy Proxy, testPair @Word64 @Word64 Proxy Proxy, testPair @Word8 @Int8 Proxy Proxy, testPair @Word8 @Word8 Proxy Proxy ] testPair :: forall a b. (IsomorphicTo a b, Eq a, Arbitrary a, Show a, Typeable a, Typeable b) => Proxy a -> Proxy b -> TestTree testPair _ _ = testProperty name $ \a -> a === from @b (from @a a) where name = show (typeOf (undefined :: a)) <> "/" <> show (typeOf (undefined :: b)) isomorphism-class-0.1.0.10/test/Test/0000755000000000000000000000000007346545000015472 5ustar0000000000000000isomorphism-class-0.1.0.10/test/Test/ExtraInstances.hs0000644000000000000000000000240407346545000020761 0ustar0000000000000000{-# OPTIONS_GHC -Wno-orphans #-} module Test.ExtraInstances () where import qualified Data.ByteString.Builder as ByteStringBuilder import qualified Data.Text.Lazy.Builder as TextLazyBuilder import qualified Data.Vector.Generic as VectorGeneric import qualified Data.Vector.Primitive as VectorPrimitive import Rebase.Prelude import Test.QuickCheck import Test.QuickCheck.Instances () instance (Arbitrary a, VectorPrimitive.Prim a) => Arbitrary (VectorPrimitive.Vector a) where arbitrary = arbitraryVector shrink = shrinkVector instance Arbitrary TextLazyBuilder.Builder where arbitrary = TextLazyBuilder.fromText <$> arbitrary shrink = shrinkMap TextLazyBuilder.fromLazyText TextLazyBuilder.toLazyText instance Eq ByteStringBuilder.Builder where (==) = on (==) ByteStringBuilder.toLazyByteString instance Arbitrary ByteStringBuilder.Builder where arbitrary = ByteStringBuilder.byteString <$> arbitrary shrink = shrinkMap ByteStringBuilder.lazyByteString ByteStringBuilder.toLazyByteString arbitraryVector :: (VectorGeneric.Vector v a, Arbitrary a) => Gen (v a) arbitraryVector = VectorGeneric.fromList <$> arbitrary shrinkVector :: (VectorGeneric.Vector v a, Arbitrary a) => v a -> [v a] shrinkVector = fmap VectorGeneric.fromList . shrink . VectorGeneric.toList