lawful-conversions (empty) → 0.1
raw patch · 60 files changed
+1866/−0 lines, 60 filesdep +QuickCheckdep +basedep +bytestring
Dependencies added: QuickCheck, base, bytestring, containers, hashable, lawful-conversions, primitive, profunctors, quickcheck-instances, rebase, tasty, tasty-quickcheck, text, unordered-containers, vector
Files
- CHANGELOG.md +0/−0
- LICENSE +22/−0
- lawful-conversions.cabal +121/−0
- src/library/LawfulConversions.hs +111/−0
- src/library/LawfulConversions/Classes.hs +5/−0
- src/library/LawfulConversions/Classes/Is.hs +36/−0
- src/library/LawfulConversions/Classes/IsMany.hs +44/−0
- src/library/LawfulConversions/Classes/IsSome.hs +53/−0
- src/library/LawfulConversions/Optics.hs +21/−0
- src/library/LawfulConversions/Prelude.hs +89/−0
- src/library/LawfulConversions/Properties.hs +94/−0
- src/library/LawfulConversions/Proxies.hs +3/−0
- src/library/LawfulConversions/Proxies/ViaIsSome.hs +72/−0
- src/library/LawfulConversions/Relations.hs +45/−0
- src/library/LawfulConversions/Relations/BoxedVectorAndList.hs +21/−0
- src/library/LawfulConversions/Relations/BoxedVectorAndSeq.hs +22/−0
- src/library/LawfulConversions/Relations/ByteArrayAndByteString.hs +24/−0
- src/library/LawfulConversions/Relations/ByteArrayAndLazyByteString.hs +25/−0
- src/library/LawfulConversions/Relations/ByteArrayAndLazyByteStringBuilder.hs +25/−0
- src/library/LawfulConversions/Relations/ByteArrayAndShortByteString.hs +24/−0
- src/library/LawfulConversions/Relations/ByteArrayAndTextArray.hs +28/−0
- src/library/LawfulConversions/Relations/ByteArrayAndWord8List.hs +22/−0
- src/library/LawfulConversions/Relations/ByteStringAndLazyByteString.hs +21/−0
- src/library/LawfulConversions/Relations/ByteStringAndLazyByteStringBuilder.hs +22/−0
- src/library/LawfulConversions/Relations/ByteStringAndShortByteString.hs +21/−0
- src/library/LawfulConversions/Relations/ByteStringAndText.hs +17/−0
- src/library/LawfulConversions/Relations/ByteStringAndTextArray.hs +28/−0
- src/library/LawfulConversions/Relations/ByteStringAndWord8List.hs +21/−0
- src/library/LawfulConversions/Relations/Int16AndWord16.hs +20/−0
- src/library/LawfulConversions/Relations/Int32AndWord32.hs +20/−0
- src/library/LawfulConversions/Relations/Int64AndWord64.hs +20/−0
- src/library/LawfulConversions/Relations/Int8AndWord8.hs +20/−0
- src/library/LawfulConversions/Relations/IntAndWord.hs +20/−0
- src/library/LawfulConversions/Relations/IntMapAndMapOfInt.hs +22/−0
- src/library/LawfulConversions/Relations/IntSetAndSetOfInt.hs +20/−0
- src/library/LawfulConversions/Relations/LazyByteStringAndLazyByteStringBuilder.hs +21/−0
- src/library/LawfulConversions/Relations/LazyByteStringAndLazyText.hs +13/−0
- src/library/LawfulConversions/Relations/LazyByteStringAndShortByteString.hs +22/−0
- src/library/LawfulConversions/Relations/LazyByteStringAndTextArray.hs +35/−0
- src/library/LawfulConversions/Relations/LazyByteStringAndWord8List.hs +21/−0
- src/library/LawfulConversions/Relations/LazyByteStringBuilderAndShortByteString.hs +24/−0
- src/library/LawfulConversions/Relations/LazyByteStringBuilderAndTextArray.hs +34/−0
- src/library/LawfulConversions/Relations/LazyByteStringBuilderAndWord8List.hs +22/−0
- src/library/LawfulConversions/Relations/LazyTextAndLazyTextBuilder.hs +24/−0
- src/library/LawfulConversions/Relations/LazyTextAndStrictTextBuilder.hs +27/−0
- src/library/LawfulConversions/Relations/LazyTextAndString.hs +12/−0
- src/library/LawfulConversions/Relations/LazyTextAndText.hs +21/−0
- src/library/LawfulConversions/Relations/LazyTextBuilderAndStrictTextBuilder.hs +28/−0
- src/library/LawfulConversions/Relations/LazyTextBuilderAndString.hs +13/−0
- src/library/LawfulConversions/Relations/LazyTextBuilderAndText.hs +24/−0
- src/library/LawfulConversions/Relations/ListAndSeq.hs +21/−0
- src/library/LawfulConversions/Relations/ShortByteStringAndTextArray.hs +28/−0
- src/library/LawfulConversions/Relations/ShortByteStringAndWord8List.hs +22/−0
- src/library/LawfulConversions/Relations/StrictTextBuilderAndString.hs +17/−0
- src/library/LawfulConversions/Relations/StrictTextBuilderAndText.hs +26/−0
- src/library/LawfulConversions/Relations/StringAndText.hs +16/−0
- src/library/LawfulConversions/Relations/TextArrayAndWord8List.hs +24/−0
- src/library/LawfulConversions/TextCompat/Array.hs +45/−0
- src/test/Main.hs +127/−0
- src/test/Test/ExtraInstances.hs +20/−0
+ CHANGELOG.md view
+ LICENSE view
@@ -0,0 +1,22 @@+Copyright (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.
+ lawful-conversions.cabal view
@@ -0,0 +1,121 @@+cabal-version: 3.0+name: lawful-conversions+version: 0.1+synopsis: Lawful typeclasses for conversion between types+category: Conversion+homepage: https://github.com/nikita-volkov/lawful-conversions+bug-reports: https://github.com/nikita-volkov/lawful-conversions/issues+author: Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>+copyright: (c) 2022 Nikita Volkov+license: MIT+license-file: LICENSE+extra-source-files:+ CHANGELOG.md++source-repository head+ type: git+ location: git://github.com/nikita-volkov/lawful-conversions.git++common language-settings+ default-language: Haskell2010+ default-extensions:+ BlockArguments+ DefaultSignatures+ FlexibleContexts+ FlexibleInstances+ MagicHash+ MultiParamTypeClasses+ NoImplicitPrelude+ ScopedTypeVariables+ TypeApplications+ UndecidableSuperClasses++library+ import: language-settings+ hs-source-dirs: src/library+ exposed-modules: LawfulConversions+ other-modules:+ LawfulConversions.Classes+ LawfulConversions.Classes.Is+ LawfulConversions.Classes.IsMany+ LawfulConversions.Classes.IsSome+ LawfulConversions.Optics+ LawfulConversions.Prelude+ LawfulConversions.Properties+ LawfulConversions.Proxies+ LawfulConversions.Proxies.ViaIsSome+ LawfulConversions.Relations+ LawfulConversions.Relations.BoxedVectorAndList+ LawfulConversions.Relations.BoxedVectorAndSeq+ LawfulConversions.Relations.ByteArrayAndByteString+ LawfulConversions.Relations.ByteArrayAndLazyByteString+ LawfulConversions.Relations.ByteArrayAndLazyByteStringBuilder+ LawfulConversions.Relations.ByteArrayAndShortByteString+ LawfulConversions.Relations.ByteArrayAndTextArray+ LawfulConversions.Relations.ByteArrayAndWord8List+ LawfulConversions.Relations.ByteStringAndLazyByteString+ LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder+ LawfulConversions.Relations.ByteStringAndShortByteString+ LawfulConversions.Relations.ByteStringAndText+ LawfulConversions.Relations.ByteStringAndTextArray+ LawfulConversions.Relations.ByteStringAndWord8List+ LawfulConversions.Relations.Int16AndWord16+ LawfulConversions.Relations.Int32AndWord32+ LawfulConversions.Relations.Int64AndWord64+ LawfulConversions.Relations.Int8AndWord8+ LawfulConversions.Relations.IntAndWord+ LawfulConversions.Relations.IntMapAndMapOfInt+ LawfulConversions.Relations.IntSetAndSetOfInt+ LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder+ LawfulConversions.Relations.LazyByteStringAndLazyText+ LawfulConversions.Relations.LazyByteStringAndShortByteString+ LawfulConversions.Relations.LazyByteStringAndTextArray+ LawfulConversions.Relations.LazyByteStringAndWord8List+ LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString+ LawfulConversions.Relations.LazyByteStringBuilderAndTextArray+ LawfulConversions.Relations.LazyByteStringBuilderAndWord8List+ LawfulConversions.Relations.LazyTextAndLazyTextBuilder+ LawfulConversions.Relations.LazyTextAndStrictTextBuilder+ LawfulConversions.Relations.LazyTextAndString+ LawfulConversions.Relations.LazyTextAndText+ LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder+ LawfulConversions.Relations.LazyTextBuilderAndString+ LawfulConversions.Relations.LazyTextBuilderAndText+ LawfulConversions.Relations.ListAndSeq+ LawfulConversions.Relations.ShortByteStringAndTextArray+ LawfulConversions.Relations.ShortByteStringAndWord8List+ LawfulConversions.Relations.StrictTextBuilderAndString+ LawfulConversions.Relations.StrictTextBuilderAndText+ LawfulConversions.Relations.StringAndText+ LawfulConversions.Relations.TextArrayAndWord8List+ LawfulConversions.TextCompat.Array++ build-depends:+ QuickCheck >=2.13 && <3,+ base >=4.12 && <5,+ bytestring >=0.10 && <0.13,+ containers >=0.6 && <0.8,+ hashable >=1 && <2,+ primitive >=0.7 && <0.10,+ profunctors >=5 && <6,+ text >=1.2 && <2.2,+ 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: src/test+ main-is: Main.hs+ other-modules: Test.ExtraInstances+ build-depends:+ QuickCheck >=2.13 && <3,+ bytestring >=0.11.1.0 && <0.13,+ lawful-conversions,+ primitive >=0.7 && <0.10,+ quickcheck-instances >=0.3.32 && <0.4,+ rebase >=1.15 && <2,+ tasty >=1.2.3 && <2,+ tasty-quickcheck >=0.10.1 && <0.11,+ text >=1.2 && <3,
+ src/library/LawfulConversions.hs view
@@ -0,0 +1,111 @@+-- |+-- Lawful typeclasses capturing three main patterns of bidirectional mapping. The typeclasses form a layered hierarchy with ascending strictness of laws.+--+-- 1. `IsSome`: Smart constructor+--+-- 2. `IsMany`: Lossy conversion+--+-- 3. `Is`: Isomorphism+--+-- = The 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.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 most 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, their behaviour not being evident to+-- the user and no way to check whether an instance is correct.+--+-- This library tackles this problem with a lawful typeclass hierarchy, making it+-- evident what any of its instances do and it provides property-tests for you+-- to validate your instances.+--+-- = Conversions+--+-- The main part of the API is two functions: 'to' and 'from'. Both+-- perform a conversion between two types. The main difference between them+-- is in what the first type application parameter specifies. E.g.:+--+-- > toString = to @String+--+-- > fromText = from @Text+--+-- The types should be self-evident:+--+-- > > :t to @String+-- > to @String :: IsSome String b => b -> String+--+-- > > :t from @Text+-- > from @Text :: IsMany Text b => Text -> b+--+-- 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 or the reader.+--+-- == Examples+--+-- @+-- renderNameAndHeight :: 'Text' -> 'Int' -> 'Text'+-- renderNameAndHeight name height =+-- 'from' @'Data.Text.Encoding.StrictTextBuilder' $+-- "Height of " <> 'to' name <> " is " <> 'to' (show height)+-- @+--+-- @+-- combineEncodings :: 'Data.ByteString.Short.ShortByteString' -> 'Data.Primitive.ByteArray' -> ['Word8'] -> 'Data.ByteString.Lazy.ByteString'+-- combineEncodings a b c =+-- 'from' @'Data.ByteString.Builder.Builder' $+-- 'to' a <> 'to' b <> 'to' c+-- @+--+-- = Partial conversions+--+-- This library also captures the pattern of smart constructors via the 'IsSome' class, which associates a total 'to' conversion with its partial inverse 'maybeFrom'.+--+-- This captures the codec relationship between types.+-- E.g.,+--+-- - Every 'Int16' can be losslessly converted into 'Int32', but not every 'Int32' can be losslessly converted into 'Int16'.+--+-- - Every 'Text' can be converted into 'ByteString' via UTF-8 encoding, but not every 'ByteString' forms a valid UTF-8 sequence.+--+-- - Every URL can be uniquely represented as 'Text', but most 'Text's are not URLs unfortunately.+module LawfulConversions+ ( -- * Typeclasses+ IsSome (..),+ IsMany (..),+ Is,++ -- * Optics+ isSomePrism,+ isManyIso,+ isIso,++ -- * Instance derivation++ -- | Proxy data-types useful for deriving various standard instances using the @DerivingVia@ extension.+ module LawfulConversions.Proxies,++ -- * Testing+ module LawfulConversions.Properties,+ )+where++import LawfulConversions.Classes+import LawfulConversions.Optics+import LawfulConversions.Properties+import LawfulConversions.Proxies+import LawfulConversions.Relations ()
+ src/library/LawfulConversions/Classes.hs view
@@ -0,0 +1,5 @@+module LawfulConversions.Classes (module Exports) where++import LawfulConversions.Classes.Is as Exports+import LawfulConversions.Classes.IsMany as Exports+import LawfulConversions.Classes.IsSome as Exports
+ src/library/LawfulConversions/Classes/Is.hs view
@@ -0,0 +1,36 @@+module LawfulConversions.Classes.Is where++import LawfulConversions.Classes.IsMany++-- | 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 @Is a b@ as \"/B/ is /A/\".+--+-- === Laws+--+-- /B/ is isomorphic to /A/ if and only if there exists a conversion from /B/+-- to /A/ ('LawfulConversions.Classes.IsSome.to') and a conversion from /A/ to /B/ ('from') such that:+--+-- - @'from' . 'LawfulConversions.Classes.IsSome.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.+--+-- - @'LawfulConversions.Classes.IsSome.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.+--+-- === Testing+--+-- For testing whether your instances conform to these laws use 'LawfulConversions.isProperties'.+--+-- === Instance Definition+--+-- For each pair of isomorphic types (/A/ and /B/) the compiler will require+-- you to define six instances, namely: @Is A B@ and @Is B A@, @IsMany A B@ and @IsMany B A@, @IsSome A B@ and @IsSome B A@.+class (IsMany a b, Is b a) => Is a b++-- | Any type is isomorphic to itself.+instance Is a a
+ src/library/LawfulConversions/Classes/IsMany.hs view
@@ -0,0 +1,44 @@+module LawfulConversions.Classes.IsMany where++import LawfulConversions.Classes.IsSome++-- |+-- Lossy or canonicalizing conversion.+-- Captures mappings from multiple alternative inputs into one output.+--+-- E.g.,+--+-- - `ByteString` can be decoded into `Text` with UTF-8 leniently, replacing the invalid chars with a default char.+--+-- - `String` has a wider range of supported chars than `Text`, so some chars get replaced too.+--+-- === Laws+--+-- ==== 'from' is an inverse of 'to'+--+-- > \sup -> sup == from (to sup)+--+-- === Testing+--+-- For testing whether your instances conform to these laws use 'LawfulConversions.isManyProperties'.+class (IsSome sup sub) => IsMany sup sub where+ -- |+ -- Possibly lossy inverse of 'to'.+ -- [Surjection](https://en.wikipedia.org/wiki/Surjective_function) from @sup@ to @sub@.+ --+ -- Particularly useful in combination with the @TypeApplications@ extension,+ -- where it allows to specify the input type, e.g.:+ --+ -- > fromText :: IsMany Text sub => Text -> sub+ -- > fromText = from @Text+ --+ -- The first type application of the 'to' function on the other hand specifies+ -- the output data type.+ from :: sup -> sub++ -- |+ -- Requires the presence of 'IsSome' in reverse direction.+ default from :: (IsSome sub sup) => sup -> sub+ from = to++instance IsMany sup sup
+ src/library/LawfulConversions/Classes/IsSome.hs view
@@ -0,0 +1,53 @@+module LawfulConversions.Classes.IsSome where++import LawfulConversions.Prelude++-- |+-- Evidence that all values of type @sub@ form a subset of all values of type @sup@.+--+-- [From Wikipedia](https://en.wikipedia.org/wiki/Subset):+--+-- In mathematics, a set A is a subset of a set B if all elements of A are also elements of B; B is then a superset of A. It is possible for A and B to be equal; if they are unequal, then A is a proper subset of B. The relationship of one set being a subset of another is called inclusion (or sometimes containment). A is a subset of B may also be expressed as B includes (or contains) A or A is included (or contained) in B. A k-subset is a subset with k elements.+--+-- === Laws+--+-- ==== 'to' is injective+--+-- For every two values of type @sub@ that are not equal converting with 'to' will always produce values that are not equal.+--+-- > \(a, b) -> a == b || to a /= to b+--+-- ==== 'maybeFrom' is an inverse of 'to'+--+-- For all values of @sub@ converting to @sup@ and then attempting to convert back to @sub@ always succeeds and produces a value that is equal to the original.+--+-- > \a -> maybeFrom (to a) == Just a+--+-- === Testing+--+-- For testing whether your instances conform to these laws use 'LawfulConversions.isSomeProperties'.+class IsSome sup sub where+ -- |+ -- Convert a value of a subset type to a superset type.+ --+ -- This function is injective non-surjective.+ to :: sub -> sup++ -- |+ -- [Partial inverse](https://en.wikipedia.org/wiki/Inverse_function#Partial_inverses) of 'to'.+ maybeFrom :: sup -> Maybe sub++ -- |+ -- Requires the presence of 'IsSome' in reverse direction.+ default maybeFrom :: (IsSome sub sup) => sup -> Maybe sub+ maybeFrom = Just . to++-- | Every type is isomorphic to itself.+instance IsSome a a where+ to = id+ maybeFrom = Just . id++-- | The empty set has no elements, and therefore is vacuously a subset of any set.+instance IsSome sup Void where+ to = absurd+ maybeFrom = const Nothing
+ src/library/LawfulConversions/Optics.hs view
@@ -0,0 +1,21 @@+module LawfulConversions.Optics where++import Data.Profunctor+import LawfulConversions.Classes+import LawfulConversions.Prelude++-- | Van-Laarhoven-style Prism, compatible with the \"lens\" library.+isSomePrism :: (IsSome a b, Choice p, Applicative f) => p b (f b) -> p a (f a)+isSomePrism =+ dimap+ (\s -> maybe (Left s) Right (maybeFrom s))+ (either pure (fmap to))+ . right'++-- | Van-Laarhoven-style Isomorphism, compatible with the \"lens\" library.+isManyIso :: (IsMany a b, Profunctor p, Functor f) => p b (f b) -> p a (f a)+isManyIso = dimap from (fmap to)++-- | Van-Laarhoven-style Isomorphism, compatible with the \"lens\" library.+isIso :: (Is a b, Profunctor p, Functor f) => p b (f b) -> p a (f a)+isIso = isManyIso
+ src/library/LawfulConversions/Prelude.hs view
@@ -0,0 +1,89 @@+module LawfulConversions.Prelude+ ( module Exports,+ as,+ )+where++import Control.Applicative as Exports+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 hiding (unzip)+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.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, (.))++as :: proxy c -> c -> c+as = flip asProxyTypeOf
+ src/library/LawfulConversions/Properties.hs view
@@ -0,0 +1,94 @@+module LawfulConversions.Properties+ ( isSomeProperties,+ isManyProperties,+ isProperties,+ )+where++import LawfulConversions.Classes+import LawfulConversions.Prelude+import Test.QuickCheck++-- |+-- Properties testing whether an instance satisfies the laws of 'IsSome'.+--+-- The instance is identified via the proxy types that you provide.+--+-- E.g., here's how you can integrate it into an Hspec test-suite:+--+-- > spec = do+-- > describe "IsSome laws" do+-- > traverse_+-- > (uncurry prop)+-- > (isSomeProperties @Int32 @Int16 Proxy Proxy)+isSomeProperties ::+ (IsSome a b, Eq a, Eq b, Show a, Show b, Arbitrary b) =>+ Proxy a ->+ Proxy b ->+ [(String, Property)]+isSomeProperties aProxy bProxy =+ [ ( "'to' is injective",+ property \a b ->+ a /= b ==>+ to' a =/= to' b+ ),+ ( "'maybeFrom' is an inverse of 'to'",+ property \a ->+ maybeFrom' (to' a) === Just a+ )+ ]+ where+ to' = as aProxy . to . as bProxy+ maybeFrom' = fmap (as bProxy) . maybeFrom . as aProxy++-- |+-- Properties testing whether an instance satisfies the laws of 'IsMany'.+--+-- The instance is identified via the proxy types that you provide.+--+-- E.g., here's how you can integrate it into an Hspec test-suite:+--+-- > spec = do+-- > describe "IsMany laws" do+-- > traverse_+-- > (uncurry prop)+-- > (isManyProperties @String @Text Proxy Proxy)+isManyProperties ::+ (IsMany a b, Eq a, Eq b, Show a, Show b, Arbitrary b) =>+ Proxy a ->+ Proxy b ->+ [(String, Property)]+isManyProperties aProxy bProxy =+ ( "'from' is an inverse of 'to'",+ property \b -> b === from' (to' b)+ )+ : isSomeProperties aProxy bProxy+ where+ to' = as aProxy . to . as bProxy+ from' = as bProxy . from . as aProxy++-- |+-- Properties testing whether an instance satisfies the laws of 'Is'.+--+-- The instance is identified via the proxy types that you provide.+--+-- E.g., here's how you can integrate it into an Hspec test-suite:+--+-- > spec = do+-- > describe "Is laws" do+-- > traverse_+-- > (uncurry prop)+-- > (isProperties @Int32 @Word32 Proxy Proxy)+isProperties ::+ (Is a b, Eq a, Eq b, Show a, Show b, Arbitrary a, Arbitrary b) =>+ Proxy a ->+ Proxy b ->+ [(String, Property)]+isProperties aProxy bProxy =+ ( "'to' is an inverse of 'from'",+ property \b -> b === to' (from' b)+ )+ : isManyProperties aProxy bProxy+ where+ to' = as aProxy . to . as bProxy+ from' = as bProxy . from . as aProxy
+ src/library/LawfulConversions/Proxies.hs view
@@ -0,0 +1,3 @@+module LawfulConversions.Proxies (module Exports) where++import LawfulConversions.Proxies.ViaIsSome as Exports
+ src/library/LawfulConversions/Proxies/ViaIsSome.hs view
@@ -0,0 +1,72 @@+module LawfulConversions.Proxies.ViaIsSome where++import LawfulConversions.Classes+import LawfulConversions.Prelude+import qualified Test.QuickCheck as QuickCheck++-- |+-- Helper for deriving common instances on types which have an instance of @'IsSome' sup@ using the @DerivingVia@ extension.+--+-- E.g.,+--+-- > newtype Percent = Percent Double+-- > deriving newtype (Show, Eq, Ord)+-- > deriving (Read, Arbitrary) via (ViaIsSome Double Percent)+-- >+-- > instance IsSome Double Percent where+-- > to (Percent double) = double+-- > maybeFrom double =+-- > if double < 0 || double > 1+-- > then Nothing+-- > else Just (Percent double)+--+-- In the code above all the instances that are able to construct the values of 'Percent' are automatically derived based on the @IsSome Double Percent@ instance.+-- This guarantees that they only construct values that pass thru the checks defined in 'maybeFrom'.+newtype ViaIsSome sup sub = ViaIsSome sub++instance (IsSome sup sub) => IsSome sup (ViaIsSome sup sub) where+ to (ViaIsSome a) = to a+ maybeFrom = fmap ViaIsSome . maybeFrom++instance IsSome sub (ViaIsSome sup sub) where+ to = coerce++instance IsSome (ViaIsSome sup sub) sub where+ to = coerce++instance IsMany sub (ViaIsSome sup sub)++instance IsMany (ViaIsSome sup sub) sub++instance Is sub (ViaIsSome sup sub)++instance Is (ViaIsSome sup sub) sub++instance (IsSome sup sub, Show sup) => Show (ViaIsSome sup sub) where+ show (ViaIsSome a) = show (to @sup a)++instance (IsSome sup sub, Read sup) => Read (ViaIsSome sup sub) where+ readPrec = do+ sup <- readPrec+ case maybeFrom @sup sup of+ Just a -> pure (ViaIsSome a)+ Nothing -> fail "Value is not from the subset"++instance (IsSome sup sub, IsString sup) => IsString (ViaIsSome sup sub) where+ fromString =+ maybe (error "Value is not from the subset") ViaIsSome . maybeFrom @sup . fromString++instance (IsSome sup sub, Eq sup) => Eq (ViaIsSome sup sub) where+ (==) = on (==) (to @sup)++instance (IsSome sup sub, Ord sup) => Ord (ViaIsSome sup sub) where+ compare = on compare (to @sup)++instance (IsSome sup sub, QuickCheck.Arbitrary sup) => QuickCheck.Arbitrary (ViaIsSome sup sub) where+ arbitrary =+ QuickCheck.suchThatMap QuickCheck.arbitrary (maybeFrom @sup)+ shrink value = do+ shrunkValue <- QuickCheck.shrink (to @sup value)+ shrunkValue+ & maybeFrom+ & maybeToList
+ src/library/LawfulConversions/Relations.hs view
@@ -0,0 +1,45 @@+module LawfulConversions.Relations () where++import LawfulConversions.Relations.BoxedVectorAndList ()+import LawfulConversions.Relations.BoxedVectorAndSeq ()+import LawfulConversions.Relations.ByteArrayAndByteString ()+import LawfulConversions.Relations.ByteArrayAndLazyByteString ()+import LawfulConversions.Relations.ByteArrayAndLazyByteStringBuilder ()+import LawfulConversions.Relations.ByteArrayAndShortByteString ()+import LawfulConversions.Relations.ByteArrayAndTextArray ()+import LawfulConversions.Relations.ByteArrayAndWord8List ()+import LawfulConversions.Relations.ByteStringAndLazyByteString ()+import LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder ()+import LawfulConversions.Relations.ByteStringAndShortByteString ()+import LawfulConversions.Relations.ByteStringAndText ()+import LawfulConversions.Relations.ByteStringAndTextArray ()+import LawfulConversions.Relations.ByteStringAndWord8List ()+import LawfulConversions.Relations.Int16AndWord16 ()+import LawfulConversions.Relations.Int32AndWord32 ()+import LawfulConversions.Relations.Int64AndWord64 ()+import LawfulConversions.Relations.Int8AndWord8 ()+import LawfulConversions.Relations.IntAndWord ()+import LawfulConversions.Relations.IntMapAndMapOfInt ()+import LawfulConversions.Relations.IntSetAndSetOfInt ()+import LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder ()+import LawfulConversions.Relations.LazyByteStringAndLazyText ()+import LawfulConversions.Relations.LazyByteStringAndShortByteString ()+import LawfulConversions.Relations.LazyByteStringAndTextArray ()+import LawfulConversions.Relations.LazyByteStringAndWord8List ()+import LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString ()+import LawfulConversions.Relations.LazyByteStringBuilderAndTextArray ()+import LawfulConversions.Relations.LazyByteStringBuilderAndWord8List ()+import LawfulConversions.Relations.LazyTextAndLazyTextBuilder ()+import LawfulConversions.Relations.LazyTextAndStrictTextBuilder ()+import LawfulConversions.Relations.LazyTextAndString ()+import LawfulConversions.Relations.LazyTextAndText ()+import LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder ()+import LawfulConversions.Relations.LazyTextBuilderAndString ()+import LawfulConversions.Relations.LazyTextBuilderAndText ()+import LawfulConversions.Relations.ListAndSeq ()+import LawfulConversions.Relations.ShortByteStringAndTextArray ()+import LawfulConversions.Relations.ShortByteStringAndWord8List ()+import LawfulConversions.Relations.StrictTextBuilderAndString ()+import LawfulConversions.Relations.StrictTextBuilderAndText ()+import LawfulConversions.Relations.StringAndText ()+import LawfulConversions.Relations.TextArrayAndWord8List ()
+ src/library/LawfulConversions/Relations/BoxedVectorAndList.hs view
@@ -0,0 +1,21 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.BoxedVectorAndList where++import qualified Data.Vector+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome (Vector a) [a] where+ to = Data.Vector.fromList++instance IsSome [a] (Vector a) where+ to = Data.Vector.toList++instance IsMany (Vector a) [a]++instance IsMany [a] (Vector a)++instance Is (Vector a) [a]++instance Is [a] (Vector a)
+ src/library/LawfulConversions/Relations/BoxedVectorAndSeq.hs view
@@ -0,0 +1,22 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.BoxedVectorAndSeq where++import qualified Data.Sequence+import qualified Data.Vector+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome (Vector a) (Seq a) where+ to = Data.Vector.fromList . toList++instance IsSome (Seq a) (Vector a) where+ to = Data.Sequence.fromList . Data.Vector.toList++instance IsMany (Vector a) (Seq a)++instance IsMany (Seq a) (Vector a)++instance Is (Vector a) (Seq a)++instance Is (Seq a) (Vector a)
+ src/library/LawfulConversions/Relations/ByteArrayAndByteString.hs view
@@ -0,0 +1,24 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteArrayAndByteString where++import qualified Data.ByteString.Short+import qualified Data.Primitive.ByteArray+import LawfulConversions.Classes+import LawfulConversions.Prelude+import LawfulConversions.Relations.ByteArrayAndShortByteString ()+import LawfulConversions.Relations.ByteStringAndShortByteString ()++instance IsSome Data.Primitive.ByteArray.ByteArray ByteString where+ to = to . to @Data.ByteString.Short.ShortByteString++instance IsSome ByteString Data.Primitive.ByteArray.ByteArray where+ to = to . to @Data.ByteString.Short.ShortByteString++instance IsMany Data.Primitive.ByteArray.ByteArray ByteString++instance IsMany ByteString Data.Primitive.ByteArray.ByteArray++instance Is Data.Primitive.ByteArray.ByteArray ByteString++instance Is ByteString Data.Primitive.ByteArray.ByteArray
+ src/library/LawfulConversions/Relations/ByteArrayAndLazyByteString.hs view
@@ -0,0 +1,25 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteArrayAndLazyByteString where++import qualified Data.ByteString.Lazy+import qualified Data.ByteString.Short+import qualified Data.Primitive.ByteArray+import LawfulConversions.Classes+import LawfulConversions.Prelude+import LawfulConversions.Relations.ByteArrayAndShortByteString ()+import LawfulConversions.Relations.LazyByteStringAndShortByteString ()++instance IsSome Data.ByteString.Lazy.ByteString Data.Primitive.ByteArray.ByteArray where+ to = to . to @Data.ByteString.Short.ShortByteString++instance IsSome Data.Primitive.ByteArray.ByteArray Data.ByteString.Lazy.ByteString where+ to = to . to @Data.ByteString.Short.ShortByteString++instance IsMany Data.Primitive.ByteArray.ByteArray Data.ByteString.Lazy.ByteString++instance IsMany Data.ByteString.Lazy.ByteString Data.Primitive.ByteArray.ByteArray++instance Is Data.Primitive.ByteArray.ByteArray Data.ByteString.Lazy.ByteString++instance Is Data.ByteString.Lazy.ByteString Data.Primitive.ByteArray.ByteArray
+ src/library/LawfulConversions/Relations/ByteArrayAndLazyByteStringBuilder.hs view
@@ -0,0 +1,25 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteArrayAndLazyByteStringBuilder where++import qualified Data.ByteString.Builder+import qualified Data.ByteString.Short+import qualified Data.Primitive.ByteArray+import LawfulConversions.Classes+import LawfulConversions.Prelude+import LawfulConversions.Relations.ByteArrayAndShortByteString ()+import LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString ()++instance IsSome Data.Primitive.ByteArray.ByteArray Data.ByteString.Builder.Builder where+ to = to . to @Data.ByteString.Short.ShortByteString++instance IsSome Data.ByteString.Builder.Builder Data.Primitive.ByteArray.ByteArray where+ to = to . to @Data.ByteString.Short.ShortByteString++instance IsMany Data.Primitive.ByteArray.ByteArray Data.ByteString.Builder.Builder++instance IsMany Data.ByteString.Builder.Builder Data.Primitive.ByteArray.ByteArray++instance Is Data.Primitive.ByteArray.ByteArray Data.ByteString.Builder.Builder++instance Is Data.ByteString.Builder.Builder Data.Primitive.ByteArray.ByteArray
+ src/library/LawfulConversions/Relations/ByteArrayAndShortByteString.hs view
@@ -0,0 +1,24 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteArrayAndShortByteString where++import qualified Data.ByteString.Short+import qualified Data.ByteString.Short.Internal+import qualified Data.Primitive.ByteArray+import LawfulConversions.Classes++instance IsSome Data.ByteString.Short.ShortByteString Data.Primitive.ByteArray.ByteArray where+ to (Data.Primitive.ByteArray.ByteArray array) =+ Data.ByteString.Short.Internal.SBS array++instance IsSome Data.Primitive.ByteArray.ByteArray Data.ByteString.Short.ShortByteString where+ to (Data.ByteString.Short.Internal.SBS array) =+ Data.Primitive.ByteArray.ByteArray array++instance IsMany Data.Primitive.ByteArray.ByteArray Data.ByteString.Short.ShortByteString++instance IsMany Data.ByteString.Short.ShortByteString Data.Primitive.ByteArray.ByteArray++instance Is Data.Primitive.ByteArray.ByteArray Data.ByteString.Short.ShortByteString++instance Is Data.ByteString.Short.ShortByteString Data.Primitive.ByteArray.ByteArray
+ src/library/LawfulConversions/Relations/ByteArrayAndTextArray.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteArrayAndTextArray where++#if !MIN_VERSION_text(2,1,0)++import qualified Data.Primitive.ByteArray+import qualified Data.Text.Array+import LawfulConversions.Classes+import LawfulConversions.Prelude+import qualified LawfulConversions.TextCompat.Array++instance IsSome Data.Primitive.ByteArray.ByteArray Data.Text.Array.Array where+ to = LawfulConversions.TextCompat.Array.toByteArray++instance IsSome Data.Text.Array.Array Data.Primitive.ByteArray.ByteArray where+ to = LawfulConversions.TextCompat.Array.fromByteArray++instance IsMany Data.Primitive.ByteArray.ByteArray Data.Text.Array.Array++instance IsMany Data.Text.Array.Array Data.Primitive.ByteArray.ByteArray++instance Is Data.Primitive.ByteArray.ByteArray Data.Text.Array.Array++instance Is Data.Text.Array.Array Data.Primitive.ByteArray.ByteArray++#endif
+ src/library/LawfulConversions/Relations/ByteArrayAndWord8List.hs view
@@ -0,0 +1,22 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteArrayAndWord8List where++import qualified Data.Primitive.ByteArray+import LawfulConversions.Classes+import LawfulConversions.Prelude+import LawfulConversions.Relations.ByteArrayAndShortByteString ()++instance IsSome Data.Primitive.ByteArray.ByteArray [Word8] where+ to = fromList++instance IsSome [Word8] Data.Primitive.ByteArray.ByteArray where+ to = toList++instance IsMany Data.Primitive.ByteArray.ByteArray [Word8]++instance IsMany [Word8] Data.Primitive.ByteArray.ByteArray++instance Is Data.Primitive.ByteArray.ByteArray [Word8]++instance Is [Word8] Data.Primitive.ByteArray.ByteArray
+ src/library/LawfulConversions/Relations/ByteStringAndLazyByteString.hs view
@@ -0,0 +1,21 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteStringAndLazyByteString where++import qualified Data.ByteString.Lazy+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome ByteString Data.ByteString.Lazy.ByteString where+ to = Data.ByteString.Lazy.toStrict++instance IsSome Data.ByteString.Lazy.ByteString ByteString where+ to = Data.ByteString.Lazy.fromStrict++instance IsMany ByteString Data.ByteString.Lazy.ByteString++instance IsMany Data.ByteString.Lazy.ByteString ByteString++instance Is ByteString Data.ByteString.Lazy.ByteString++instance Is Data.ByteString.Lazy.ByteString ByteString
+ src/library/LawfulConversions/Relations/ByteStringAndLazyByteStringBuilder.hs view
@@ -0,0 +1,22 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder where++import qualified Data.ByteString.Builder+import qualified Data.ByteString.Lazy+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome ByteString Data.ByteString.Builder.Builder where+ to = Data.ByteString.Lazy.toStrict . Data.ByteString.Builder.toLazyByteString++instance IsSome Data.ByteString.Builder.Builder ByteString where+ to = Data.ByteString.Builder.byteString++instance IsMany Data.ByteString.Builder.Builder ByteString++instance IsMany ByteString Data.ByteString.Builder.Builder++instance Is Data.ByteString.Builder.Builder ByteString++instance Is ByteString Data.ByteString.Builder.Builder
+ src/library/LawfulConversions/Relations/ByteStringAndShortByteString.hs view
@@ -0,0 +1,21 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteStringAndShortByteString where++import qualified Data.ByteString.Short+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome ByteString Data.ByteString.Short.ShortByteString where+ to = Data.ByteString.Short.fromShort++instance IsSome Data.ByteString.Short.ShortByteString ByteString where+ to = Data.ByteString.Short.toShort++instance IsMany ByteString Data.ByteString.Short.ShortByteString++instance IsMany Data.ByteString.Short.ShortByteString ByteString++instance Is ByteString Data.ByteString.Short.ShortByteString++instance Is Data.ByteString.Short.ShortByteString ByteString
+ src/library/LawfulConversions/Relations/ByteStringAndText.hs view
@@ -0,0 +1,17 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteStringAndText where++import qualified Data.Text.Encoding+import qualified Data.Text.Encoding.Error+import LawfulConversions.Classes+import LawfulConversions.Prelude++-- | UTF-8 codec.+instance IsSome ByteString Text where+ to = Data.Text.Encoding.encodeUtf8+ maybeFrom = either (const Nothing) Just . Data.Text.Encoding.decodeUtf8'++-- | Lenient UTF-8 decoding.+instance IsMany ByteString Text where+ from = Data.Text.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
+ src/library/LawfulConversions/Relations/ByteStringAndTextArray.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteStringAndTextArray where++#if !MIN_VERSION_text(2,1,0)++import qualified Data.ByteString.Short+import qualified Data.Text.Array+import LawfulConversions.Classes+import LawfulConversions.Prelude+import qualified LawfulConversions.TextCompat.Array++instance IsSome ByteString Data.Text.Array.Array where+ to = Data.ByteString.Short.fromShort . LawfulConversions.TextCompat.Array.toShortByteString++instance IsSome Data.Text.Array.Array ByteString where+ to = LawfulConversions.TextCompat.Array.fromShortByteString . Data.ByteString.Short.toShort++instance IsMany ByteString Data.Text.Array.Array++instance IsMany Data.Text.Array.Array ByteString++instance Is ByteString Data.Text.Array.Array++instance Is Data.Text.Array.Array ByteString++#endif
+ src/library/LawfulConversions/Relations/ByteStringAndWord8List.hs view
@@ -0,0 +1,21 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ByteStringAndWord8List where++import qualified Data.ByteString+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome ByteString [Word8] where+ to = Data.ByteString.pack++instance IsSome [Word8] ByteString where+ to = Data.ByteString.unpack++instance IsMany ByteString [Word8]++instance IsMany [Word8] ByteString++instance Is ByteString [Word8]++instance Is [Word8] ByteString
+ src/library/LawfulConversions/Relations/Int16AndWord16.hs view
@@ -0,0 +1,20 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.Int16AndWord16 where++import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Int16 Word16 where+ to = fromIntegral++instance IsSome Word16 Int16 where+ to = fromIntegral++instance IsMany Int16 Word16++instance IsMany Word16 Int16++instance Is Int16 Word16++instance Is Word16 Int16
+ src/library/LawfulConversions/Relations/Int32AndWord32.hs view
@@ -0,0 +1,20 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.Int32AndWord32 where++import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Int32 Word32 where+ to = fromIntegral++instance IsSome Word32 Int32 where+ to = fromIntegral++instance IsMany Int32 Word32++instance IsMany Word32 Int32++instance Is Int32 Word32++instance Is Word32 Int32
+ src/library/LawfulConversions/Relations/Int64AndWord64.hs view
@@ -0,0 +1,20 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.Int64AndWord64 where++import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Int64 Word64 where+ to = fromIntegral++instance IsSome Word64 Int64 where+ to = fromIntegral++instance IsMany Int64 Word64++instance IsMany Word64 Int64++instance Is Int64 Word64++instance Is Word64 Int64
+ src/library/LawfulConversions/Relations/Int8AndWord8.hs view
@@ -0,0 +1,20 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.Int8AndWord8 where++import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Int8 Word8 where+ to = fromIntegral++instance IsSome Word8 Int8 where+ to = fromIntegral++instance IsMany Int8 Word8++instance IsMany Word8 Int8++instance Is Int8 Word8++instance Is Word8 Int8
+ src/library/LawfulConversions/Relations/IntAndWord.hs view
@@ -0,0 +1,20 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.IntAndWord where++import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Int Word where+ to = fromIntegral++instance IsSome Word Int where+ to = fromIntegral++instance IsMany Int Word++instance IsMany Word Int++instance Is Int Word++instance Is Word Int
+ src/library/LawfulConversions/Relations/IntMapAndMapOfInt.hs view
@@ -0,0 +1,22 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.IntMapAndMapOfInt where++import qualified Data.IntMap.Strict+import qualified Data.Map.Strict+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome (Map Int v) (IntMap v) where+ to = Data.Map.Strict.fromList . Data.IntMap.Strict.toList++instance IsSome (IntMap v) (Map Int v) where+ to = Data.IntMap.Strict.fromList . Data.Map.Strict.toList++instance IsMany (Map Int v) (IntMap v)++instance IsMany (IntMap v) (Map Int v)++instance Is (Map Int v) (IntMap v)++instance Is (IntMap v) (Map Int v)
+ src/library/LawfulConversions/Relations/IntSetAndSetOfInt.hs view
@@ -0,0 +1,20 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.IntSetAndSetOfInt where++import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome (Set Int) IntSet where+ to = fromList . toList++instance IsSome IntSet (Set Int) where+ to = fromList . toList++instance IsMany (Set Int) IntSet++instance IsMany IntSet (Set Int)++instance Is (Set Int) IntSet++instance Is IntSet (Set Int)
+ src/library/LawfulConversions/Relations/LazyByteStringAndLazyByteStringBuilder.hs view
@@ -0,0 +1,21 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder where++import qualified Data.ByteString.Builder+import qualified Data.ByteString.Lazy+import LawfulConversions.Classes++instance IsSome Data.ByteString.Lazy.ByteString Data.ByteString.Builder.Builder where+ to = Data.ByteString.Builder.toLazyByteString++instance IsSome Data.ByteString.Builder.Builder Data.ByteString.Lazy.ByteString where+ to = Data.ByteString.Builder.lazyByteString++instance IsMany Data.ByteString.Lazy.ByteString Data.ByteString.Builder.Builder++instance IsMany Data.ByteString.Builder.Builder Data.ByteString.Lazy.ByteString++instance Is Data.ByteString.Lazy.ByteString Data.ByteString.Builder.Builder++instance Is Data.ByteString.Builder.Builder Data.ByteString.Lazy.ByteString
+ src/library/LawfulConversions/Relations/LazyByteStringAndLazyText.hs view
@@ -0,0 +1,13 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyByteStringAndLazyText where++import qualified Data.ByteString.Lazy+import qualified Data.Text.Lazy+import qualified Data.Text.Lazy.Encoding+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.ByteString.Lazy.ByteString Data.Text.Lazy.Text where+ to = Data.Text.Lazy.Encoding.encodeUtf8+ maybeFrom = either (const Nothing) Just . Data.Text.Lazy.Encoding.decodeUtf8'
+ src/library/LawfulConversions/Relations/LazyByteStringAndShortByteString.hs view
@@ -0,0 +1,22 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyByteStringAndShortByteString where++import qualified Data.ByteString.Lazy+import qualified Data.ByteString.Short+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.ByteString.Lazy.ByteString Data.ByteString.Short.ShortByteString where+ to = Data.ByteString.Lazy.fromStrict . Data.ByteString.Short.fromShort++instance IsSome Data.ByteString.Short.ShortByteString Data.ByteString.Lazy.ByteString where+ to = Data.ByteString.Short.toShort . Data.ByteString.Lazy.toStrict++instance IsMany Data.ByteString.Lazy.ByteString Data.ByteString.Short.ShortByteString++instance IsMany Data.ByteString.Short.ShortByteString Data.ByteString.Lazy.ByteString++instance Is Data.ByteString.Lazy.ByteString Data.ByteString.Short.ShortByteString++instance Is Data.ByteString.Short.ShortByteString Data.ByteString.Lazy.ByteString
+ src/library/LawfulConversions/Relations/LazyByteStringAndTextArray.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyByteStringAndTextArray where++#if !MIN_VERSION_text(2,1,0)++import qualified Data.ByteString.Lazy+import qualified Data.ByteString.Short+import qualified Data.Text.Array+import LawfulConversions.Classes+import LawfulConversions.Prelude+import qualified LawfulConversions.TextCompat.Array++instance IsSome Data.ByteString.Lazy.ByteString Data.Text.Array.Array where+ to =+ Data.ByteString.Lazy.fromStrict+ . Data.ByteString.Short.fromShort+ . LawfulConversions.TextCompat.Array.toShortByteString++instance IsSome Data.Text.Array.Array Data.ByteString.Lazy.ByteString where+ to =+ LawfulConversions.TextCompat.Array.fromShortByteString+ . Data.ByteString.Short.toShort+ . Data.ByteString.Lazy.toStrict++instance IsMany Data.Text.Array.Array Data.ByteString.Lazy.ByteString++instance IsMany Data.ByteString.Lazy.ByteString Data.Text.Array.Array++instance Is Data.Text.Array.Array Data.ByteString.Lazy.ByteString++instance Is Data.ByteString.Lazy.ByteString Data.Text.Array.Array++#endif
+ src/library/LawfulConversions/Relations/LazyByteStringAndWord8List.hs view
@@ -0,0 +1,21 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyByteStringAndWord8List where++import qualified Data.ByteString.Lazy+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.ByteString.Lazy.ByteString [Word8] where+ to = Data.ByteString.Lazy.pack++instance IsSome [Word8] Data.ByteString.Lazy.ByteString where+ to = Data.ByteString.Lazy.unpack++instance IsMany Data.ByteString.Lazy.ByteString [Word8]++instance IsMany [Word8] Data.ByteString.Lazy.ByteString++instance Is Data.ByteString.Lazy.ByteString [Word8]++instance Is [Word8] Data.ByteString.Lazy.ByteString
+ src/library/LawfulConversions/Relations/LazyByteStringBuilderAndShortByteString.hs view
@@ -0,0 +1,24 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString where++import qualified Data.ByteString.Builder+import qualified Data.ByteString.Lazy+import qualified Data.ByteString.Short+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.ByteString.Builder.Builder Data.ByteString.Short.ShortByteString where+ to = Data.ByteString.Builder.shortByteString++instance IsSome Data.ByteString.Short.ShortByteString Data.ByteString.Builder.Builder where+ to = Data.ByteString.Short.toShort . Data.ByteString.Lazy.toStrict . Data.ByteString.Builder.toLazyByteString+ maybeFrom = Just . Data.ByteString.Builder.shortByteString++instance IsMany Data.ByteString.Builder.Builder Data.ByteString.Short.ShortByteString++instance IsMany Data.ByteString.Short.ShortByteString Data.ByteString.Builder.Builder++instance Is Data.ByteString.Builder.Builder Data.ByteString.Short.ShortByteString++instance Is Data.ByteString.Short.ShortByteString Data.ByteString.Builder.Builder
+ src/library/LawfulConversions/Relations/LazyByteStringBuilderAndTextArray.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyByteStringBuilderAndTextArray where++#if !MIN_VERSION_text(2,1,0)++import qualified Data.ByteString.Builder+import qualified Data.ByteString.Lazy+import qualified Data.ByteString.Short+import qualified Data.Text.Array+import LawfulConversions.Classes+import LawfulConversions.Prelude+import qualified LawfulConversions.TextCompat.Array++instance IsSome Data.ByteString.Builder.Builder Data.Text.Array.Array where+ to = Data.ByteString.Builder.shortByteString . LawfulConversions.TextCompat.Array.toShortByteString++instance IsSome Data.Text.Array.Array Data.ByteString.Builder.Builder where+ to =+ LawfulConversions.TextCompat.Array.fromShortByteString+ . Data.ByteString.Short.toShort+ . Data.ByteString.Lazy.toStrict+ . Data.ByteString.Builder.toLazyByteString++instance IsMany Data.Text.Array.Array Data.ByteString.Builder.Builder++instance IsMany Data.ByteString.Builder.Builder Data.Text.Array.Array++instance Is Data.Text.Array.Array Data.ByteString.Builder.Builder++instance Is Data.ByteString.Builder.Builder Data.Text.Array.Array++#endif
+ src/library/LawfulConversions/Relations/LazyByteStringBuilderAndWord8List.hs view
@@ -0,0 +1,22 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyByteStringBuilderAndWord8List where++import qualified Data.ByteString.Builder+import qualified Data.ByteString.Lazy+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.ByteString.Builder.Builder [Word8] where+ to = Data.ByteString.Builder.lazyByteString . Data.ByteString.Lazy.pack++instance IsSome [Word8] Data.ByteString.Builder.Builder where+ to = Data.ByteString.Lazy.unpack . Data.ByteString.Builder.toLazyByteString++instance IsMany Data.ByteString.Builder.Builder [Word8]++instance IsMany [Word8] Data.ByteString.Builder.Builder++instance Is Data.ByteString.Builder.Builder [Word8]++instance Is [Word8] Data.ByteString.Builder.Builder
+ src/library/LawfulConversions/Relations/LazyTextAndLazyTextBuilder.hs view
@@ -0,0 +1,24 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyTextAndLazyTextBuilder where++import qualified Data.Text.Lazy+import qualified Data.Text.Lazy.Builder+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.Text.Lazy.Text Data.Text.Lazy.Builder.Builder where+ to = Data.Text.Lazy.Builder.toLazyText+ maybeFrom = Just . Data.Text.Lazy.Builder.fromLazyText++instance IsSome Data.Text.Lazy.Builder.Builder Data.Text.Lazy.Text where+ to = Data.Text.Lazy.Builder.fromLazyText+ maybeFrom = Just . Data.Text.Lazy.Builder.toLazyText++instance IsMany Data.Text.Lazy.Text Data.Text.Lazy.Builder.Builder++instance IsMany Data.Text.Lazy.Builder.Builder Data.Text.Lazy.Text++instance Is Data.Text.Lazy.Text Data.Text.Lazy.Builder.Builder++instance Is Data.Text.Lazy.Builder.Builder Data.Text.Lazy.Text
+ src/library/LawfulConversions/Relations/LazyTextAndStrictTextBuilder.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyTextAndStrictTextBuilder where++#if MIN_VERSION_text(2,0,2)++import qualified Data.Text.Encoding+import qualified Data.Text.Lazy+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.Text.Lazy.Text Data.Text.Encoding.StrictBuilder where+ to = Data.Text.Lazy.fromStrict . Data.Text.Encoding.strictBuilderToText++instance IsSome Data.Text.Encoding.StrictBuilder Data.Text.Lazy.Text where+ to = Data.Text.Encoding.textToStrictBuilder . Data.Text.Lazy.toStrict++instance IsMany Data.Text.Lazy.Text Data.Text.Encoding.StrictBuilder++instance IsMany Data.Text.Encoding.StrictBuilder Data.Text.Lazy.Text++instance Is Data.Text.Lazy.Text Data.Text.Encoding.StrictBuilder++instance Is Data.Text.Encoding.StrictBuilder Data.Text.Lazy.Text++#endif
+ src/library/LawfulConversions/Relations/LazyTextAndString.hs view
@@ -0,0 +1,12 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyTextAndString where++import qualified Data.Text.Lazy+import LawfulConversions.Classes+import LawfulConversions.Prelude+import LawfulConversions.Relations.StringAndText ()++instance IsSome String Data.Text.Lazy.Text where+ to = Data.Text.Lazy.unpack+ maybeFrom = fmap Data.Text.Lazy.fromStrict . maybeFrom
+ src/library/LawfulConversions/Relations/LazyTextAndText.hs view
@@ -0,0 +1,21 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyTextAndText where++import qualified Data.Text.Lazy+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.Text.Lazy.Text Text where+ to = Data.Text.Lazy.fromStrict++instance IsSome Text Data.Text.Lazy.Text where+ to = Data.Text.Lazy.toStrict++instance IsMany Data.Text.Lazy.Text Text++instance IsMany Text Data.Text.Lazy.Text++instance Is Data.Text.Lazy.Text Text++instance Is Text Data.Text.Lazy.Text
+ src/library/LawfulConversions/Relations/LazyTextBuilderAndStrictTextBuilder.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder where++#if MIN_VERSION_text(2,0,2)++import qualified Data.Text.Encoding+import qualified Data.Text.Lazy+import qualified Data.Text.Lazy.Builder+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.Text.Lazy.Builder.Builder Data.Text.Encoding.StrictBuilder where+ to = Data.Text.Lazy.Builder.fromText . Data.Text.Encoding.strictBuilderToText++instance IsSome Data.Text.Encoding.StrictBuilder Data.Text.Lazy.Builder.Builder where+ to = Data.Text.Encoding.textToStrictBuilder . Data.Text.Lazy.toStrict . Data.Text.Lazy.Builder.toLazyText++instance IsMany Data.Text.Lazy.Builder.Builder Data.Text.Encoding.StrictBuilder++instance IsMany Data.Text.Encoding.StrictBuilder Data.Text.Lazy.Builder.Builder++instance Is Data.Text.Lazy.Builder.Builder Data.Text.Encoding.StrictBuilder++instance Is Data.Text.Encoding.StrictBuilder Data.Text.Lazy.Builder.Builder++#endif
+ src/library/LawfulConversions/Relations/LazyTextBuilderAndString.hs view
@@ -0,0 +1,13 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyTextBuilderAndString where++import qualified Data.Text.Lazy+import qualified Data.Text.Lazy.Builder+import LawfulConversions.Classes+import LawfulConversions.Prelude+import LawfulConversions.Relations.StringAndText ()++instance IsSome String Data.Text.Lazy.Builder.Builder where+ to = Data.Text.Lazy.unpack . Data.Text.Lazy.Builder.toLazyText+ maybeFrom = fmap Data.Text.Lazy.Builder.fromText . maybeFrom
+ src/library/LawfulConversions/Relations/LazyTextBuilderAndText.hs view
@@ -0,0 +1,24 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.LazyTextBuilderAndText where++import qualified Data.Text.Lazy+import qualified Data.Text.Lazy.Builder+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Data.Text.Lazy.Builder.Builder Text where+ to = Data.Text.Lazy.Builder.fromText+ maybeFrom = Just . Data.Text.Lazy.toStrict . Data.Text.Lazy.Builder.toLazyText++instance IsSome Text Data.Text.Lazy.Builder.Builder where+ to = Data.Text.Lazy.toStrict . Data.Text.Lazy.Builder.toLazyText+ maybeFrom = Just . Data.Text.Lazy.Builder.fromText++instance IsMany Data.Text.Lazy.Builder.Builder Text++instance IsMany Text Data.Text.Lazy.Builder.Builder++instance Is Data.Text.Lazy.Builder.Builder Text++instance Is Text Data.Text.Lazy.Builder.Builder
+ src/library/LawfulConversions/Relations/ListAndSeq.hs view
@@ -0,0 +1,21 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ListAndSeq where++import qualified Data.Sequence+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome [a] (Seq a) where+ to = toList++instance IsSome (Seq a) [a] where+ to = Data.Sequence.fromList++instance IsMany [a] (Seq a)++instance IsMany (Seq a) [a]++instance Is [a] (Seq a)++instance Is (Seq a) [a]
+ src/library/LawfulConversions/Relations/ShortByteStringAndTextArray.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ShortByteStringAndTextArray where++#if !MIN_VERSION_text(2,1,0)++import qualified Data.ByteString.Short+import qualified Data.Text.Array+import LawfulConversions.Classes+import LawfulConversions.Prelude+import qualified LawfulConversions.TextCompat.Array++instance IsSome Data.ByteString.Short.ShortByteString Data.Text.Array.Array where+ to = LawfulConversions.TextCompat.Array.toShortByteString++instance IsSome Data.Text.Array.Array Data.ByteString.Short.ShortByteString where+ to = LawfulConversions.TextCompat.Array.fromShortByteString++instance IsMany Data.ByteString.Short.ShortByteString Data.Text.Array.Array++instance IsMany Data.Text.Array.Array Data.ByteString.Short.ShortByteString++instance Is Data.ByteString.Short.ShortByteString Data.Text.Array.Array++instance Is Data.Text.Array.Array Data.ByteString.Short.ShortByteString++#endif
+ src/library/LawfulConversions/Relations/ShortByteStringAndWord8List.hs view
@@ -0,0 +1,22 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.ShortByteStringAndWord8List where++import qualified Data.ByteString.Short+import LawfulConversions.Classes+import LawfulConversions.Prelude+import LawfulConversions.Relations.ByteArrayAndShortByteString ()++instance IsSome [Word8] Data.ByteString.Short.ShortByteString where+ to = Data.ByteString.Short.unpack++instance IsSome Data.ByteString.Short.ShortByteString [Word8] where+ to = Data.ByteString.Short.pack++instance IsMany [Word8] Data.ByteString.Short.ShortByteString++instance IsMany Data.ByteString.Short.ShortByteString [Word8]++instance Is [Word8] Data.ByteString.Short.ShortByteString++instance Is Data.ByteString.Short.ShortByteString [Word8]
+ src/library/LawfulConversions/Relations/StrictTextBuilderAndString.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.StrictTextBuilderAndString where++#if MIN_VERSION_text(2,0,2)++import qualified Data.Text.Encoding+import LawfulConversions.Classes+import LawfulConversions.Relations.StringAndText ()+import LawfulConversions.Prelude++instance IsSome String Data.Text.Encoding.StrictBuilder where+ to = to . Data.Text.Encoding.strictBuilderToText+ maybeFrom = fmap Data.Text.Encoding.textToStrictBuilder . maybeFrom++#endif
+ src/library/LawfulConversions/Relations/StrictTextBuilderAndText.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.StrictTextBuilderAndText where++#if MIN_VERSION_text(2,0,2)++import qualified Data.Text.Encoding+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome Text Data.Text.Encoding.StrictBuilder where+ to = Data.Text.Encoding.strictBuilderToText++instance IsSome Data.Text.Encoding.StrictBuilder Text where+ to = Data.Text.Encoding.textToStrictBuilder++instance IsMany Text Data.Text.Encoding.StrictBuilder++instance IsMany Data.Text.Encoding.StrictBuilder Text++instance Is Text Data.Text.Encoding.StrictBuilder++instance Is Data.Text.Encoding.StrictBuilder Text++#endif
+ src/library/LawfulConversions/Relations/StringAndText.hs view
@@ -0,0 +1,16 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.StringAndText where++import qualified Data.Text as Text+import LawfulConversions.Classes+import LawfulConversions.Prelude++instance IsSome String Text where+ to = Text.unpack+ maybeFrom string =+ -- FIXME: Optimize.+ let text = Text.pack string+ in if string == Text.unpack text+ then Just text+ else Nothing
+ src/library/LawfulConversions/Relations/TextArrayAndWord8List.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.TextArrayAndWord8List where++#if !MIN_VERSION_text(2,1,0)++import qualified Data.ByteString.Short+import qualified Data.Text.Array+import LawfulConversions.Classes+import LawfulConversions.Prelude+import qualified LawfulConversions.TextCompat.Array++instance IsSome Data.Text.Array.Array [Word8] where+ to = LawfulConversions.TextCompat.Array.fromShortByteString . Data.ByteString.Short.pack++instance IsSome [Word8] Data.Text.Array.Array where+ to = Data.ByteString.Short.unpack . LawfulConversions.TextCompat.Array.toShortByteString++instance Is Data.Text.Array.Array [Word8]++instance Is [Word8] Data.Text.Array.Array++#endif
+ src/library/LawfulConversions/TextCompat/Array.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE CPP #-}++module LawfulConversions.TextCompat.Array where++import qualified Data.ByteString.Short+import qualified Data.ByteString.Short.Internal+import qualified Data.Primitive.ByteArray+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++{-# INLINE fromShortByteString #-}+fromShortByteString :: Data.ByteString.Short.ShortByteString -> Array+fromShortByteString (Data.ByteString.Short.Internal.SBS arr) =+ fromUnliftedByteArray arr++{-# INLINE toShortByteString #-}+toShortByteString :: Array -> Data.ByteString.Short.ShortByteString+toShortByteString a =+ Data.ByteString.Short.Internal.SBS (toUnliftedByteArray a)++{-# INLINE fromByteArray #-}+fromByteArray :: Data.Primitive.ByteArray.ByteArray -> Array+fromByteArray (Data.Primitive.ByteArray.ByteArray arr) =+ fromUnliftedByteArray arr++{-# INLINE toByteArray #-}+toByteArray :: Array -> Data.Primitive.ByteArray.ByteArray+toByteArray a =+ Data.Primitive.ByteArray.ByteArray (toUnliftedByteArray a)
+ src/test/Main.hs view
@@ -0,0 +1,127 @@+module 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 LawfulConversions+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 @[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 @TextLazy.Text Proxy Proxy,+ testPair @Text @TextLazyBuilder.Builder Proxy Proxy,+ testPair @TextLazy.Text @TextLazy.Text 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 @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 :: (Is a b, Eq a, Eq b, Arbitrary a, Show a, Arbitrary b, Show b, Typeable a, Typeable b) => Proxy a -> Proxy b -> TestTree+testPair superp subp =+ isProperties superp subp+ & fmap (uncurry testProperty)+ & testGroup groupName+ where+ groupName =+ mconcat+ [ show (typeOf (asProxyTypeOf undefined superp)),+ "/",+ show (typeOf (asProxyTypeOf undefined subp))+ ]
+ src/test/Test/ExtraInstances.hs view
@@ -0,0 +1,20 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module Test.ExtraInstances () where++import qualified Data.ByteString.Builder as ByteStringBuilder+import qualified Data.Text.Lazy.Builder as TextLazyBuilder+import Rebase.Prelude+import Test.QuickCheck+import Test.QuickCheck.Instances ()++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