packages feed

lawful-conversions 0.1.7 → 0.4.0

raw patch · 75 files changed

Files

CHANGELOG.md view
@@ -0,0 +1,19 @@+# v0.4++## Breaking++- Removed interpretation-based relations: UTF-8, ISO-8601, and UUID. +  - Relations that depend on a specific encoding or format choice violate the library's principle of unambiguous structural conversion — there is no single canonical way to encode Text as bytes or render a UTCTime as a string.++# v0.3++## Breaking++- `from` of `IsMany` renamed to `onfrom`.+- New `from` function added, which is an alias to `to` with type arguments flipped.++# v0.2++## Breaking++- Added more tests in `isManyProperties` and an `Arbitrary` constraint on its parameter `a`.
lawful-conversions.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: lawful-conversions-version: 0.1.7+version: 0.4.0 synopsis: Lawful typeclasses for bidirectional conversion between types category: Conversion homepage: https://github.com/nikita-volkov/lawful-conversions@@ -50,6 +50,8 @@   evident what any of its instances do and it provides property-tests for you   to validate your instances. +  The laws and the concepts are based on set and category theories.+   = Prior work and acknowledgements    This library is an offspring of the "[isomorphism-class](https://hackage.haskell.org/package/isomorphism-class)" library, expanding upon the patterns discovered there. Both libraries are maintained letting their designs compete.@@ -83,13 +85,14 @@   hs-source-dirs: src/library   exposed-modules: LawfulConversions   other-modules:-    LawfulConversions.Classes+    LawfulConversions.Algebra     LawfulConversions.Optics     LawfulConversions.Prelude     LawfulConversions.Properties     LawfulConversions.Proxies     LawfulConversions.Proxies.ViaIsSome     LawfulConversions.Relations+    LawfulConversions.Relations.Any     LawfulConversions.Relations.BoxedVectorAndList     LawfulConversions.Relations.BoxedVectorAndSeq     LawfulConversions.Relations.ByteArrayAndByteString@@ -100,17 +103,9 @@     LawfulConversions.Relations.ByteArrayAndWord8List     LawfulConversions.Relations.ByteStringAndLazyByteString     LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder-    LawfulConversions.Relations.ByteStringAndLazyText     LawfulConversions.Relations.ByteStringAndShortByteString-    LawfulConversions.Relations.ByteStringAndString-    LawfulConversions.Relations.ByteStringAndText     LawfulConversions.Relations.ByteStringAndTextArray     LawfulConversions.Relations.ByteStringAndWord8List-    LawfulConversions.Relations.DayAndLazyText-    LawfulConversions.Relations.DayAndLazyTextBuilder-    LawfulConversions.Relations.DayAndStrictTextBuilder-    LawfulConversions.Relations.DayAndString-    LawfulConversions.Relations.DayAndText     LawfulConversions.Relations.Int16AndWord16     LawfulConversions.Relations.Int32AndWord32     LawfulConversions.Relations.Int64AndWord64@@ -119,10 +114,7 @@     LawfulConversions.Relations.IntMapAndMapOfInt     LawfulConversions.Relations.IntSetAndSetOfInt     LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder-    LawfulConversions.Relations.LazyByteStringAndLazyText     LawfulConversions.Relations.LazyByteStringAndShortByteString-    LawfulConversions.Relations.LazyByteStringAndString-    LawfulConversions.Relations.LazyByteStringAndText     LawfulConversions.Relations.LazyByteStringAndTextArray     LawfulConversions.Relations.LazyByteStringAndWord8List     LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString@@ -132,40 +124,29 @@     LawfulConversions.Relations.LazyTextAndStrictTextBuilder     LawfulConversions.Relations.LazyTextAndString     LawfulConversions.Relations.LazyTextAndText-    LawfulConversions.Relations.LazyTextAndUtcTime-    LawfulConversions.Relations.LazyTextAndUuid     LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder     LawfulConversions.Relations.LazyTextBuilderAndString     LawfulConversions.Relations.LazyTextBuilderAndText-    LawfulConversions.Relations.LazyTextBuilderAndUtcTime-    LawfulConversions.Relations.LazyTextBuilderAndUuid     LawfulConversions.Relations.ListAndSeq     LawfulConversions.Relations.ShortByteStringAndTextArray     LawfulConversions.Relations.ShortByteStringAndWord8List     LawfulConversions.Relations.StrictTextBuilderAndString     LawfulConversions.Relations.StrictTextBuilderAndText-    LawfulConversions.Relations.StrictTextBuilderAndUtcTime-    LawfulConversions.Relations.StrictTextBuilderAndUuid     LawfulConversions.Relations.StringAndText-    LawfulConversions.Relations.StringAndUtcTime-    LawfulConversions.Relations.StringAndUuid-    LawfulConversions.Relations.TextAndUtcTime-    LawfulConversions.Relations.TextAndUuid     LawfulConversions.Relations.TextArrayAndWord8List+    LawfulConversions.Relations.Void     LawfulConversions.TextCompat.Array    build-depends:     QuickCheck >=2.13 && <3,     base >=4.12 && <5,     bytestring >=0.10 && <0.13,-    containers >=0.6 && <0.8,+    containers >=0.6 && <0.9,     hashable >=1 && <2,     primitive >=0.7 && <0.10,     profunctors >=5 && <6,     text >=1.2 && <2.2,-    time >=1.9 && <2,     unordered-containers >=0.2 && <0.3,-    uuid-types >=1.0 && <1.1,     vector >=0.12 && <0.14,  test-suite test@@ -179,7 +160,7 @@     bytestring >=0.11.1.0 && <0.13,     lawful-conversions,     primitive >=0.7 && <0.10,-    quickcheck-instances >=0.3.32 && <0.4,+    quickcheck-instances >=0.3.32 && <0.5,     rebase >=1.15 && <2,     tasty >=1.2.3 && <2,     tasty-quickcheck >=0.11 && <0.12,
src/library/LawfulConversions.hs view
@@ -15,7 +15,7 @@ -- > to @String :: IsSome String b => b -> String -- -- > > :t from @Text--- > from @Text :: IsMany Text b => Text -> b+-- > from @Text :: IsSome a Text => Text -> a -- -- 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@@ -30,13 +30,6 @@ --     'to' a <> 'to' b <> 'to' c -- @ ----- @--- renderNameAndHeight :: 'Text' -> 'Int' -> 'Text'--- renderNameAndHeight name height =---   'from' @'Data.Text.Encoding.StrictTextBuilder' $---     "Height of " <> 'from' name <> " is " <> 'from' (show height)--- @--- -- = 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'.@@ -72,7 +65,7 @@ -- You can also expand upon that and provide a default handling of invalid values effectively providing a lossy canonicalizing conversion ([Surjection](https://en.wikipedia.org/wiki/Surjective_function)): -- -- > instance IsMany Double Percent where--- >   from double =+-- >   onfrom double = -- >     if double < 0 -- >       then Percent 0 -- >       else if double > 1@@ -88,6 +81,10 @@     Is,      -- * Combinators+    from,+    maybeTo,+    tryFrom,+    tryTo,     onto,      -- * Optics@@ -105,7 +102,7 @@   ) where -import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Optics import LawfulConversions.Properties import LawfulConversions.Proxies
+ src/library/LawfulConversions/Algebra.hs view
@@ -0,0 +1,225 @@+module LawfulConversions.Algebra where++import LawfulConversions.Prelude++-- |+-- Evidence that all values of type @b@ form a subset of all values of type @a@.+--+-- [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](https://en.wikipedia.org/wiki/Injective_function)+--+-- For every two values of type @b@ that are not equal converting with 'to' produces values that are not equal as well:+--+-- > \(b1, b2) -> b1 == b2 || to @a b1 /= to @a b2+--+-- ==== 'maybeFrom' is a [partial inverse](https://en.wikipedia.org/wiki/Inverse_function#Partial_inverses) of 'to'+--+-- For all values of @b@ converting to @a@ and then attempting to convert back to @b@ always succeeds and produces a value that is equal to the original:+--+-- > \b -> maybeFrom (to @a b) == Just b+--+-- ==== 'maybeFrom' characterizes the image of 'to'+--+-- 'maybeFrom' succeeds exactly on values that are in the image of 'to':+--+-- > \a b -> maybeFrom a == Just b ==> to b == a+--+-- ==== Mathematical foundation+--+-- These laws establish that type @b@ forms a subset of type @a@ in the mathematical sense.+-- The 'to' function provides the canonical injection, while 'maybeFrom' recognizes which values of @a@+-- correspond to values from the subset @b@.+--+-- === Testing+--+-- For testing whether your instances conform to these laws use 'LawfulConversions.isSomeProperties'.+class IsSome a b where+  -- |+  -- Convert a value of a subset type to a superset type.+  to :: b -> a++  -- |+  -- [Partial inverse](https://en.wikipedia.org/wiki/Inverse_function#Partial_inverses) of 'to'.+  maybeFrom :: a -> Maybe b++  -- |+  -- Requires the presence of 'IsSome' in reverse direction.+  default maybeFrom :: (IsSome b a) => a -> Maybe b+  maybeFrom = Just . to++-- |+-- Convert a value of a subset type to a superset type, specifying the source subset type first.+--+-- Alias to 'to' with the only difference in the argument order.+--+-- E.g.,+--+-- > fromText = from @Text+from :: forall b a. (IsSome a b) => b -> a+from = to++-- |+-- Try to convert a value of a superset type to a subset type specifying the target subset type first.+--+-- Alias to 'maybeFrom' with the only difference in the argument order.+--+-- Particularly useful in combination with the @TypeApplications@ extension,+-- where it allows to specify the target type, e.g.:+--+-- > maybeToInt16 :: Int32 -> Maybe Int16+-- > maybeToInt16 = maybeTo @Int16+--+-- > percent = maybeTo @Percent someDouble+maybeTo :: forall b a. (IsSome a b) => a -> Maybe b+maybeTo = maybeFrom++-- |+-- Like 'maybeFrom', but returns an 'Either' with the provided error on failure.+--+-- Useful for raising custom errors when conversion fails.+tryFrom :: (IsSome a b) => e -> a -> Either e b+tryFrom err a =+  case maybeFrom a of+    Just b -> Right b+    Nothing -> Left err++-- |+-- Alias to 'tryFrom', which lets you specify the target type of the conversion first using @TypeApplications@.+tryTo :: forall b a e. (IsSome a b) => e -> a -> Either e b+tryTo = tryFrom++-- |+-- 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+--+-- ==== 'onfrom' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'to'+--+-- > \b -> b == onfrom (to @a b)+--+-- ==== 'onfrom' is [surjective](https://en.wikipedia.org/wiki/Surjective_function)+--+-- Every value of type @b@ can be obtained by applying 'onfrom' to some value of type @a@:+--+-- > \b -> exists a. onfrom @a @b a == b+--+-- Note: This property cannot be directly tested with QuickCheck as it requires existential quantification.+--+-- ==== Law hierarchy+--+-- 'IsMany' extends 'IsSome', so all laws from 'IsSome' also apply here.+-- The combination ensures that 'onfrom' provides a canonical (possibly lossy) conversion from @a@ to @b@,+-- while 'to' provides the lossless injection from @b@ to @a@.+--+-- === Testing+--+-- For testing whether your instances conform to these laws use 'LawfulConversions.isManyProperties'.+class (IsSome a b) => IsMany a b where+  -- |+  -- Possibly lossy inverse of 'to'.+  -- [Surjection](https://en.wikipedia.org/wiki/Surjective_function) from @a@ to @b@.+  --+  -- Particularly useful in combination with the @TypeApplications@ extension,+  -- where it allows to specify the input type, e.g.:+  --+  -- > fromString :: IsMany String b => String -> b+  -- > fromString = onfrom @String+  --+  -- If you want to specify the output type instead, use 'onto'.+  onfrom :: a -> b++  -- |+  -- Requires the presence of 'IsSome' in reverse direction.+  default onfrom :: (IsSome b a) => a -> b+  onfrom = to++-- |+-- Alias to 'onfrom', which lets you specify the target type of the conversion first using @TypeApplications@.+--+-- In mathematics @onto@ is another name for [Surjective function](https://en.wikipedia.org/wiki/Surjective_function).+--+-- E.g.,+--+-- > lenientDecodeUtf8 = onto @Text+--+-- @+-- combineTexts :: 'Text' -> 'ByteString' -> 'Int' -> 'Text'+-- combineTexts name email height =+--   'from' @'Data.Text.Encoding.StrictTextBuilder' $+--     "Height of " <> 'to' name <> " is " <> 'onto' (show height) <> " and email is " <> 'onto' email+-- @+onto :: forall b a. (IsMany a b) => a -> b+onto = onfrom++-- | 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+--+-- ==== 'from' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'to'+--+-- For all values of /b/ converting from /b/ to /a/ and then converting from /a/ to /b/ produces the original value:+--+-- > \b -> b == from @a (to @a b)+--+-- ==== 'to' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'from'+--+-- For all values of /a/ converting from /a/ to /b/ and then converting from /b/ to /a/ produces the original value:+--+-- > \a -> a == to @a (from @a @b a)+--+-- ==== Mathematical relationship+--+-- These two laws together establish that 'to' and 'from' form a true [isomorphism](https://en.wikipedia.org/wiki/Isomorphism) between types @a@ and @b@.+-- Note that 'from' is implemented as 'to' from the reverse 'Is' instance, ensuring the symmetry required for isomorphisms.+--+-- ==== 'from' equals 'onfrom'+--+-- For isomorphic types, both ways of converting should be equivalent:+--+-- > \a -> from @a @b a == onfrom @a @b a+--+-- === 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@.+--+-- Instances of @Is@ do not define any functions and serve merely as a statement that the laws are satisfied.+--+-- ==== Example: Lazy Text and Text+--+-- @+-- instance IsSome "Data.Text.Lazy.LazyText" "Data.Text.Text" where+--   to = LazyText.'Data.Text.Lazy.fromStrict'+--+-- instance IsSome "Data.Text.Text" "Data.Text.Lazy.LazyText" where+--   to = LazyText.'Data.Text.Lazy.toStrict'+--+-- instance IsMany "Data.Text.Lazy.LazyText" "Data.Text.Text"+--+-- instance IsMany "Data.Text.Text" "Data.Text.Lazy.LazyText"+--+-- instance Is "Data.Text.Lazy.LazyText" "Data.Text.Text"+--+-- instance Is "Data.Text.Text" "Data.Text.Lazy.LazyText"+-- @+class (IsMany a b, Is b a) => Is a b
− src/library/LawfulConversions/Classes.hs
@@ -1,158 +0,0 @@-module LawfulConversions.Classes where--import LawfulConversions.Prelude---- |--- Evidence that all values of type @b@ form a subset of all values of type @a@.------ [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](https://en.wikipedia.org/wiki/Injective_function)------ For every two values of type @b@ that are not equal converting with 'to' produces values that are not equal as well:------ > \(b1, b2) -> b1 == b2 || to @a b1 /= to @a b2------ ==== 'maybeFrom' is a [partial inverse](https://en.wikipedia.org/wiki/Inverse_function#Partial_inverses) of 'to'------ For all values of @b@ converting to @a@ and then attempting to convert back to @b@ always succeeds and produces a value that is equal to the original:------ > \b -> maybeFrom (to @a b) == Just b------ === Testing------ For testing whether your instances conform to these laws use 'LawfulConversions.isSomeProperties'.-class IsSome a b where-  -- |-  -- Convert a value of a subset type to a superset type.-  to :: b -> a--  -- |-  -- [Partial inverse](https://en.wikipedia.org/wiki/Inverse_function#Partial_inverses) of 'to'.-  maybeFrom :: a -> Maybe b--  -- |-  -- Requires the presence of 'IsSome' in reverse direction.-  default maybeFrom :: (IsSome b a) => a -> Maybe b-  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 a Void where-  to = absurd-  maybeFrom = const Nothing---- |--- 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](https://en.wikipedia.org/wiki/Inverse_function) of 'to'------ > \b -> b == from (to @a b)------ === Testing------ For testing whether your instances conform to these laws use 'LawfulConversions.isManyProperties'.-class (IsSome a b) => IsMany a b where-  -- |-  -- Possibly lossy inverse of 'to'.-  -- [Surjection](https://en.wikipedia.org/wiki/Surjective_function) from @a@ to @b@.-  ---  -- Particularly useful in combination with the @TypeApplications@ extension,-  -- where it allows to specify the input type, e.g.:-  ---  -- > fromText :: IsMany Text b => Text -> b-  -- > fromText = from @Text-  ---  -- The first type application of the 'to' function on the other hand specifies-  -- the output data type.-  ---  -- If you want to specify the output type instead, use 'onto'.-  from :: a -> b--  -- |-  -- Requires the presence of 'IsSome' in reverse direction.-  default from :: (IsSome b a) => a -> b-  from = to---- |--- Alias to 'from', which lets you specify the target type of the conversion first using @TypeApplications@.------ In mathematics @onto@ is another name for [Surjective function](https://en.wikipedia.org/wiki/Surjective_function).------ E.g.,------ > lenientDecodeUtf8 = onto @Text-onto :: forall b a. (IsMany a b) => a -> b-onto = from--instance IsMany a a---- | 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------ ==== 'from' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'to'------ For all values of /b/ converting from /b/ to /a/ and then converting from /a/ to /b/ produces the original value:------ > \b -> b == from (to @a b)------ ==== 'to' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'from'------ For all values of /a/ converting from /a/ to /b/ and then converting from /b/ to /a/ produces the original value:------ > \a -> a == to (from @a @b a)------ === 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@.------ Instances of @Is@ do not define any functions and serve merely as a statement that the laws are satisfied.------ ==== Example: Lazy Text and Text------ @--- instance IsSome "Data.Text.Lazy.LazyText" "Data.Text.Text" where---   to = LazyText.'Data.Text.Lazy.fromStrict'------ instance IsSome "Data.Text.Text" "Data.Text.Lazy.LazyText" where---   to = LazyText.'Data.Text.Lazy.toStrict'------ instance IsMany "Data.Text.Lazy.LazyText" "Data.Text.Text"------ instance IsMany "Data.Text.Text" "Data.Text.Lazy.LazyText"------ instance Is "Data.Text.Lazy.LazyText" "Data.Text.Text"------ instance Is "Data.Text.Text" "Data.Text.Lazy.LazyText"--- @-class (IsMany a b, Is b a) => Is a b---- | Any type is isomorphic to itself.-instance Is a a
src/library/LawfulConversions/Optics.hs view
@@ -1,7 +1,7 @@ module LawfulConversions.Optics where  import Data.Profunctor-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  -- | Van-Laarhoven-style Prism, compatible with libraries like \"lens\" and \"optics\".@@ -14,7 +14,7 @@  -- | Van-Laarhoven-style Isomorphism, compatible with libraries like \"lens\" and \"optics\". isManyIso :: (IsMany a b, Profunctor p, Functor f) => p b (f b) -> p a (f a)-isManyIso = dimap from (fmap to)+isManyIso = dimap onfrom (fmap to)  -- | Van-Laarhoven-style Isomorphism, compatible with libraries like \"lens\" and \"optics\". isIso :: (Is a b, Profunctor p, Functor f) => p b (f b) -> p a (f a)
src/library/LawfulConversions/Prelude.hs view
@@ -55,7 +55,6 @@ import Data.Text as Exports (Text) import Data.Traversable as Exports import Data.Tuple as Exports-import Data.UUID.Types as Exports (UUID) import Data.Vector as Exports (Vector) import Data.Version as Exports import Data.Void as Exports
src/library/LawfulConversions/Properties.hs view
@@ -5,7 +5,7 @@   ) where -import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import Test.QuickCheck @@ -22,19 +22,27 @@ -- >       (uncurry prop) -- >       (isSomeProperties @Int32 @Int16 Proxy Proxy) isSomeProperties ::-  (IsSome a b, Eq a, Eq b, Show a, Show b, Arbitrary b) =>+  forall a b.+  (IsSome a b, Eq a, Eq b, Show a, Show b, Arbitrary a, Arbitrary b) =>   Proxy a ->   Proxy b ->   [(String, Property)] isSomeProperties aProxy bProxy =   [ ( "'to' is injective",-      property \a b ->-        a /= b ==>-          to' a =/= to' b+      property \b1 b2 ->+        if b1 == b2+          then property True+          else to' b1 =/= to' b2     ),     ( "'maybeFrom' is a partial inverse of 'to'",+      property \b ->+        maybeFrom' (to' b) === Just b+    ),+    ( "'maybeFrom' characterizes the image of 'to'",       property \a ->-        maybeFrom' (to' a) === Just a+        case maybeFrom' a of+          Just b -> to' b === a+          Nothing -> property True     )   ]   where@@ -54,18 +62,30 @@ -- >       (uncurry prop) -- >       (isManyProperties @String @Text Proxy Proxy) isManyProperties ::-  (IsMany a b, Eq a, Eq b, Show a, Show b, Arbitrary b) =>+  forall a b.+  (IsMany a b, Eq a, Eq b, Show a, Show b, Arbitrary a, 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+  [ ( "'onfrom' is an inverse of 'to'",+      property \b -> b === onfrom' (to' b)+    ),+    ( "'onfrom' is consistent with 'maybeFrom'",+      property \(b :: b) ->+        let a = to @a b+         in maybeFrom (to @a b) === Just (onfrom @a @b a)+    ),+    ( "'to' after 'onfrom' always succeeds with 'maybeFrom'",+      property \a ->+        let b = onfrom' a+         in maybeFrom (to' b) === Just b+    )+  ]+    <> isSomeProperties aProxy bProxy   where     to' = as aProxy . to . as bProxy-    from' = as bProxy . from . as aProxy+    onfrom' = as bProxy . onfrom . as aProxy  -- | -- Properties testing whether an instance satisfies the laws of 'Is'.@@ -85,10 +105,15 @@   Proxy b ->   [(String, Property)] isProperties aProxy bProxy =-  ( "'to' is an inverse of 'from'",-    property \b -> b === to' (from' b)-  )-    : isManyProperties aProxy bProxy+  [ ( "'to' is an inverse of 'from'",+      property \b -> b === to' (from' b)+    ),+    ( "'from' equals 'onfrom'",+      property \a -> from' a === onfrom' a+    )+  ]+    <> isManyProperties aProxy bProxy   where     to' = as aProxy . to . as bProxy     from' = as bProxy . from . as aProxy+    onfrom' = as bProxy . onfrom . as aProxy
src/library/LawfulConversions/Proxies/ViaIsSome.hs view
@@ -1,6 +1,6 @@ module LawfulConversions.Proxies.ViaIsSome where -import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import qualified Test.QuickCheck as QuickCheck 
src/library/LawfulConversions/Relations.hs view
@@ -1,5 +1,6 @@ module LawfulConversions.Relations () where +import LawfulConversions.Relations.Any () import LawfulConversions.Relations.BoxedVectorAndList () import LawfulConversions.Relations.BoxedVectorAndSeq () import LawfulConversions.Relations.ByteArrayAndByteString ()@@ -10,17 +11,9 @@ import LawfulConversions.Relations.ByteArrayAndWord8List () import LawfulConversions.Relations.ByteStringAndLazyByteString () import LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder ()-import LawfulConversions.Relations.ByteStringAndLazyText () import LawfulConversions.Relations.ByteStringAndShortByteString ()-import LawfulConversions.Relations.ByteStringAndString ()-import LawfulConversions.Relations.ByteStringAndText () import LawfulConversions.Relations.ByteStringAndTextArray () import LawfulConversions.Relations.ByteStringAndWord8List ()-import LawfulConversions.Relations.DayAndLazyText ()-import LawfulConversions.Relations.DayAndLazyTextBuilder ()-import LawfulConversions.Relations.DayAndStrictTextBuilder ()-import LawfulConversions.Relations.DayAndString ()-import LawfulConversions.Relations.DayAndText () import LawfulConversions.Relations.Int16AndWord16 () import LawfulConversions.Relations.Int32AndWord32 () import LawfulConversions.Relations.Int64AndWord64 ()@@ -29,10 +22,7 @@ import LawfulConversions.Relations.IntMapAndMapOfInt () import LawfulConversions.Relations.IntSetAndSetOfInt () import LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder ()-import LawfulConversions.Relations.LazyByteStringAndLazyText () import LawfulConversions.Relations.LazyByteStringAndShortByteString ()-import LawfulConversions.Relations.LazyByteStringAndString ()-import LawfulConversions.Relations.LazyByteStringAndText () import LawfulConversions.Relations.LazyByteStringAndTextArray () import LawfulConversions.Relations.LazyByteStringAndWord8List () import LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString ()@@ -42,23 +32,14 @@ import LawfulConversions.Relations.LazyTextAndStrictTextBuilder () import LawfulConversions.Relations.LazyTextAndString () import LawfulConversions.Relations.LazyTextAndText ()-import LawfulConversions.Relations.LazyTextAndUtcTime ()-import LawfulConversions.Relations.LazyTextAndUuid () import LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder () import LawfulConversions.Relations.LazyTextBuilderAndString () import LawfulConversions.Relations.LazyTextBuilderAndText ()-import LawfulConversions.Relations.LazyTextBuilderAndUtcTime ()-import LawfulConversions.Relations.LazyTextBuilderAndUuid () import LawfulConversions.Relations.ListAndSeq () import LawfulConversions.Relations.ShortByteStringAndTextArray () import LawfulConversions.Relations.ShortByteStringAndWord8List () import LawfulConversions.Relations.StrictTextBuilderAndString () import LawfulConversions.Relations.StrictTextBuilderAndText ()-import LawfulConversions.Relations.StrictTextBuilderAndUtcTime ()-import LawfulConversions.Relations.StrictTextBuilderAndUuid () import LawfulConversions.Relations.StringAndText ()-import LawfulConversions.Relations.StringAndUtcTime ()-import LawfulConversions.Relations.StringAndUuid ()-import LawfulConversions.Relations.TextAndUtcTime ()-import LawfulConversions.Relations.TextAndUuid () import LawfulConversions.Relations.TextArrayAndWord8List ()+import LawfulConversions.Relations.Void ()
+ src/library/LawfulConversions/Relations/Any.hs view
@@ -0,0 +1,17 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.Any where++import LawfulConversions.Algebra+import LawfulConversions.Prelude++-- | Any type is isomorphic to itself.+instance IsSome a a where+  to = id+  maybeFrom = Just . id++-- | Any type is isomorphic to itself.+instance IsMany a a++-- | Any type is isomorphic to itself.+instance Is a a
src/library/LawfulConversions/Relations/BoxedVectorAndList.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.BoxedVectorAndList where  import qualified Data.Vector-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome (Vector a) [a] where
src/library/LawfulConversions/Relations/BoxedVectorAndSeq.hs view
@@ -4,7 +4,7 @@  import qualified Data.Sequence import qualified Data.Vector-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome (Vector a) (Seq a) where
src/library/LawfulConversions/Relations/ByteArrayAndByteString.hs view
@@ -4,7 +4,7 @@  import qualified Data.ByteString.Short import qualified Data.Primitive.ByteArray-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import LawfulConversions.Relations.ByteArrayAndShortByteString () import LawfulConversions.Relations.ByteStringAndShortByteString ()
src/library/LawfulConversions/Relations/ByteArrayAndLazyByteString.hs view
@@ -5,7 +5,7 @@ import qualified Data.ByteString.Lazy import qualified Data.ByteString.Short import qualified Data.Primitive.ByteArray-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import LawfulConversions.Relations.ByteArrayAndShortByteString () import LawfulConversions.Relations.LazyByteStringAndShortByteString ()
src/library/LawfulConversions/Relations/ByteArrayAndLazyByteStringBuilder.hs view
@@ -5,7 +5,7 @@ import qualified Data.ByteString.Builder import qualified Data.ByteString.Short import qualified Data.Primitive.ByteArray-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import LawfulConversions.Relations.ByteArrayAndShortByteString () import LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString ()
src/library/LawfulConversions/Relations/ByteArrayAndShortByteString.hs view
@@ -5,7 +5,7 @@ import qualified Data.ByteString.Short import qualified Data.ByteString.Short.Internal import qualified Data.Primitive.ByteArray-import LawfulConversions.Classes+import LawfulConversions.Algebra  instance IsSome Data.ByteString.Short.ShortByteString Data.Primitive.ByteArray.ByteArray where   to (Data.Primitive.ByteArray.ByteArray array) =
src/library/LawfulConversions/Relations/ByteArrayAndTextArray.hs view
@@ -7,7 +7,7 @@  import qualified Data.Primitive.ByteArray import qualified Data.Text.Array-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import qualified LawfulConversions.TextCompat.Array 
src/library/LawfulConversions/Relations/ByteArrayAndWord8List.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.ByteArrayAndWord8List where  import qualified Data.Primitive.ByteArray-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import LawfulConversions.Relations.ByteArrayAndShortByteString () 
src/library/LawfulConversions/Relations/ByteStringAndLazyByteString.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.ByteStringAndLazyByteString where  import qualified Data.ByteString.Lazy-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome ByteString Data.ByteString.Lazy.ByteString where
src/library/LawfulConversions/Relations/ByteStringAndLazyByteStringBuilder.hs view
@@ -4,7 +4,7 @@  import qualified Data.ByteString.Builder import qualified Data.ByteString.Lazy-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome ByteString Data.ByteString.Builder.Builder where
− src/library/LawfulConversions/Relations/ByteStringAndLazyText.hs
@@ -1,19 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.ByteStringAndLazyText where--import qualified Data.ByteString.Lazy-import qualified Data.Text.Encoding.Error-import qualified Data.Text.Lazy-import qualified Data.Text.Lazy.Encoding-import LawfulConversions.Classes-import LawfulConversions.Prelude---- | UTF-8 codec.-instance IsSome ByteString Data.Text.Lazy.Text where-  to = Data.ByteString.Lazy.toStrict . Data.Text.Lazy.Encoding.encodeUtf8-  maybeFrom = either (const Nothing) Just . Data.Text.Lazy.Encoding.decodeUtf8' . Data.ByteString.Lazy.fromStrict---- | Lenient UTF-8 decoding.-instance IsMany ByteString Data.Text.Lazy.Text where-  from = Data.Text.Lazy.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode . Data.ByteString.Lazy.fromStrict
src/library/LawfulConversions/Relations/ByteStringAndShortByteString.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.ByteStringAndShortByteString where  import qualified Data.ByteString.Short-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome ByteString Data.ByteString.Short.ShortByteString where
− src/library/LawfulConversions/Relations/ByteStringAndString.hs
@@ -1,18 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.ByteStringAndString where--import qualified Data.Text-import qualified Data.Text.Encoding-import qualified Data.Text.Encoding.Error-import LawfulConversions.Classes-import LawfulConversions.Prelude---- | UTF-8 codec.-instance IsSome ByteString String where-  to = Data.Text.Encoding.encodeUtf8 . Data.Text.pack-  maybeFrom = either (const Nothing) (Just . Data.Text.unpack) . Data.Text.Encoding.decodeUtf8'---- | Lenient UTF-8 decoding.-instance IsMany ByteString String where-  from = Data.Text.unpack . Data.Text.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
− src/library/LawfulConversions/Relations/ByteStringAndText.hs
@@ -1,17 +0,0 @@-{-# 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
@@ -7,7 +7,7 @@  import qualified Data.ByteString.Short import qualified Data.Text.Array-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import qualified LawfulConversions.TextCompat.Array 
src/library/LawfulConversions/Relations/ByteStringAndWord8List.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.ByteStringAndWord8List where  import qualified Data.ByteString-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome ByteString [Word8] where
− src/library/LawfulConversions/Relations/DayAndLazyText.hs
@@ -1,15 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.DayAndLazyText where--import qualified Data.Text.Lazy-import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.DayAndString ()-import LawfulConversions.Relations.LazyTextAndString ()---- | Implements ISO-8601.-instance IsSome Data.Text.Lazy.Text Day where-  to = fromString . to-  maybeFrom = maybeFrom @String . to
− src/library/LawfulConversions/Relations/DayAndLazyTextBuilder.hs
@@ -1,15 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.DayAndLazyTextBuilder where--import qualified Data.Text.Lazy.Builder-import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.DayAndString ()-import LawfulConversions.Relations.LazyTextBuilderAndString ()---- | Implements ISO-8601.-instance IsSome Data.Text.Lazy.Builder.Builder Day where-  to = fromString . to-  maybeFrom = maybeFrom @String . to
− src/library/LawfulConversions/Relations/DayAndStrictTextBuilder.hs
@@ -1,36 +0,0 @@-{-# LANGUAGE CPP #-}-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.DayAndStrictTextBuilder where--#if MIN_VERSION_text(2,1,2)--import qualified Data.Text.Encoding-import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.StrictTextBuilderAndString ()-import LawfulConversions.Relations.StringAndText ()-import LawfulConversions.Relations.DayAndString ()---- | Implements ISO-8601.-instance IsSome Data.Text.Encoding.StrictTextBuilder Day where-  to = from . to @String-  maybeFrom = maybeFrom @String . to--#elif MIN_VERSION_text(2,0,2)--import qualified Data.Text.Encoding-import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.StrictTextBuilderAndString ()-import LawfulConversions.Relations.StringAndText ()-import LawfulConversions.Relations.DayAndString ()---- | Implements ISO-8601.-instance IsSome Data.Text.Encoding.StrictBuilder Day where-  to = from . to @String-  maybeFrom = maybeFrom @String . to--#endif
− src/library/LawfulConversions/Relations/DayAndString.hs
@@ -1,13 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.DayAndString where--import Data.Time-import Data.Time.Format.ISO8601-import LawfulConversions.Classes-import LawfulConversions.Prelude---- | Implements ISO-8601.-instance IsSome String Day where-  to = iso8601Show-  maybeFrom = iso8601ParseM
− src/library/LawfulConversions/Relations/DayAndText.hs
@@ -1,14 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.DayAndText where--import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.DayAndString ()-import LawfulConversions.Relations.StringAndText ()---- | Implements ISO-8601.-instance IsSome Text Day where-  to = fromString . to-  maybeFrom = maybeFrom @String . to
src/library/LawfulConversions/Relations/Int16AndWord16.hs view
@@ -2,7 +2,7 @@  module LawfulConversions.Relations.Int16AndWord16 where -import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Int16 Word16 where
src/library/LawfulConversions/Relations/Int32AndWord32.hs view
@@ -2,7 +2,7 @@  module LawfulConversions.Relations.Int32AndWord32 where -import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Int32 Word32 where
src/library/LawfulConversions/Relations/Int64AndWord64.hs view
@@ -2,7 +2,7 @@  module LawfulConversions.Relations.Int64AndWord64 where -import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Int64 Word64 where
src/library/LawfulConversions/Relations/Int8AndWord8.hs view
@@ -2,7 +2,7 @@  module LawfulConversions.Relations.Int8AndWord8 where -import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Int8 Word8 where
src/library/LawfulConversions/Relations/IntAndWord.hs view
@@ -2,7 +2,7 @@  module LawfulConversions.Relations.IntAndWord where -import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Int Word where
src/library/LawfulConversions/Relations/IntMapAndMapOfInt.hs view
@@ -4,7 +4,7 @@  import qualified Data.IntMap.Strict import qualified Data.Map.Strict-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome (Map Int v) (IntMap v) where
src/library/LawfulConversions/Relations/IntSetAndSetOfInt.hs view
@@ -2,7 +2,7 @@  module LawfulConversions.Relations.IntSetAndSetOfInt where -import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome (Set Int) IntSet where
src/library/LawfulConversions/Relations/LazyByteStringAndLazyByteStringBuilder.hs view
@@ -4,7 +4,7 @@  import qualified Data.ByteString.Builder import qualified Data.ByteString.Lazy-import LawfulConversions.Classes+import LawfulConversions.Algebra  instance IsSome Data.ByteString.Lazy.ByteString Data.ByteString.Builder.Builder where   to = Data.ByteString.Builder.toLazyByteString
− src/library/LawfulConversions/Relations/LazyByteStringAndLazyText.hs
@@ -1,19 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.LazyByteStringAndLazyText where--import qualified Data.ByteString.Lazy-import qualified Data.Text.Encoding.Error-import qualified Data.Text.Lazy-import qualified Data.Text.Lazy.Encoding-import LawfulConversions.Classes-import LawfulConversions.Prelude---- | UTF-8 codec.-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'---- | Lenient UTF-8 decoding.-instance IsMany Data.ByteString.Lazy.ByteString Data.Text.Lazy.Text where-  from = Data.Text.Lazy.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
src/library/LawfulConversions/Relations/LazyByteStringAndShortByteString.hs view
@@ -4,7 +4,7 @@  import qualified Data.ByteString.Lazy import qualified Data.ByteString.Short-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.ByteString.Lazy.ByteString Data.ByteString.Short.ShortByteString where
− src/library/LawfulConversions/Relations/LazyByteStringAndString.hs
@@ -1,19 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.LazyByteStringAndString where--import qualified Data.ByteString.Lazy-import qualified Data.Text.Encoding.Error-import qualified Data.Text.Lazy-import qualified Data.Text.Lazy.Encoding-import LawfulConversions.Classes-import LawfulConversions.Prelude---- | UTF-8 codec.-instance IsSome Data.ByteString.Lazy.ByteString String where-  to = Data.Text.Lazy.Encoding.encodeUtf8 . Data.Text.Lazy.pack-  maybeFrom = either (const Nothing) (Just . Data.Text.Lazy.unpack) . Data.Text.Lazy.Encoding.decodeUtf8'---- | Lenient UTF-8 decoding.-instance IsMany Data.ByteString.Lazy.ByteString String where-  from = Data.Text.Lazy.unpack . Data.Text.Lazy.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
− src/library/LawfulConversions/Relations/LazyByteStringAndText.hs
@@ -1,20 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.LazyByteStringAndText where--import qualified Data.ByteString.Lazy-import qualified Data.Text-import qualified Data.Text.Encoding.Error-import qualified Data.Text.Lazy-import qualified Data.Text.Lazy.Encoding-import LawfulConversions.Classes-import LawfulConversions.Prelude---- | UTF-8 codec.-instance IsSome Data.ByteString.Lazy.ByteString Data.Text.Text where-  to = Data.Text.Lazy.Encoding.encodeUtf8 . Data.Text.Lazy.fromStrict-  maybeFrom = either (const Nothing) (Just . Data.Text.Lazy.toStrict) . Data.Text.Lazy.Encoding.decodeUtf8'---- | Lenient UTF-8 decoding.-instance IsMany Data.ByteString.Lazy.ByteString Data.Text.Text where-  from = Data.Text.Lazy.toStrict . Data.Text.Lazy.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
src/library/LawfulConversions/Relations/LazyByteStringAndTextArray.hs view
@@ -8,7 +8,7 @@ import qualified Data.ByteString.Lazy import qualified Data.ByteString.Short import qualified Data.Text.Array-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import qualified LawfulConversions.TextCompat.Array 
src/library/LawfulConversions/Relations/LazyByteStringAndWord8List.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.LazyByteStringAndWord8List where  import qualified Data.ByteString.Lazy-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.ByteString.Lazy.ByteString [Word8] where
src/library/LawfulConversions/Relations/LazyByteStringBuilderAndShortByteString.hs view
@@ -5,7 +5,7 @@ import qualified Data.ByteString.Builder import qualified Data.ByteString.Lazy import qualified Data.ByteString.Short-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.ByteString.Builder.Builder Data.ByteString.Short.ShortByteString where
src/library/LawfulConversions/Relations/LazyByteStringBuilderAndTextArray.hs view
@@ -9,7 +9,7 @@ import qualified Data.ByteString.Lazy import qualified Data.ByteString.Short import qualified Data.Text.Array-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import qualified LawfulConversions.TextCompat.Array 
src/library/LawfulConversions/Relations/LazyByteStringBuilderAndWord8List.hs view
@@ -4,7 +4,7 @@  import qualified Data.ByteString.Builder import qualified Data.ByteString.Lazy-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.ByteString.Builder.Builder [Word8] where
src/library/LawfulConversions/Relations/LazyTextAndLazyTextBuilder.hs view
@@ -4,7 +4,7 @@  import qualified Data.Text.Lazy import qualified Data.Text.Lazy.Builder-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.Text.Lazy.Text Data.Text.Lazy.Builder.Builder where
src/library/LawfulConversions/Relations/LazyTextAndStrictTextBuilder.hs view
@@ -7,7 +7,7 @@  import qualified Data.Text.Encoding import qualified Data.Text.Lazy-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.Text.Lazy.Text Data.Text.Encoding.StrictTextBuilder where@@ -28,7 +28,7 @@  import qualified Data.Text.Encoding import qualified Data.Text.Lazy-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.Text.Lazy.Text Data.Text.Encoding.StrictBuilder where
src/library/LawfulConversions/Relations/LazyTextAndString.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.LazyTextAndString where  import qualified Data.Text.Lazy-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import LawfulConversions.Relations.StringAndText () @@ -12,4 +12,4 @@   maybeFrom = fmap Data.Text.Lazy.fromStrict . maybeFrom  instance IsMany String Data.Text.Lazy.Text where-  from = fromString+  onfrom = fromString
src/library/LawfulConversions/Relations/LazyTextAndText.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.LazyTextAndText where  import qualified Data.Text.Lazy-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.Text.Lazy.Text Text where
− src/library/LawfulConversions/Relations/LazyTextAndUtcTime.hs
@@ -1,15 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.LazyTextAndUtcTime where--import qualified Data.Text.Lazy-import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.LazyTextAndString ()-import LawfulConversions.Relations.StringAndUtcTime ()---- | Implements ISO-8601.-instance IsSome Data.Text.Lazy.Text UTCTime where-  to = fromString . to-  maybeFrom = maybeFrom @String . to
− src/library/LawfulConversions/Relations/LazyTextAndUuid.hs
@@ -1,12 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.LazyTextAndUuid where--import qualified Data.Text.Lazy-import qualified Data.UUID.Types-import LawfulConversions.Classes-import LawfulConversions.Prelude--instance IsSome Data.Text.Lazy.Text UUID where-  to = Data.Text.Lazy.fromStrict . Data.UUID.Types.toText-  maybeFrom = Data.UUID.Types.fromText . Data.Text.Lazy.toStrict
src/library/LawfulConversions/Relations/LazyTextBuilderAndStrictTextBuilder.hs view
@@ -8,7 +8,7 @@ import qualified Data.Text.Encoding import qualified Data.Text.Lazy import qualified Data.Text.Lazy.Builder-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.Text.Lazy.Builder.Builder Data.Text.Encoding.StrictTextBuilder where@@ -30,7 +30,7 @@ import qualified Data.Text.Encoding import qualified Data.Text.Lazy import qualified Data.Text.Lazy.Builder-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.Text.Lazy.Builder.Builder Data.Text.Encoding.StrictBuilder where
src/library/LawfulConversions/Relations/LazyTextBuilderAndString.hs view
@@ -4,7 +4,7 @@  import qualified Data.Text.Lazy import qualified Data.Text.Lazy.Builder-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import LawfulConversions.Relations.StringAndText () @@ -13,4 +13,4 @@   maybeFrom = fmap Data.Text.Lazy.Builder.fromText . maybeFrom  instance IsMany String Data.Text.Lazy.Builder.Builder where-  from = fromString+  onfrom = fromString
src/library/LawfulConversions/Relations/LazyTextBuilderAndText.hs view
@@ -4,7 +4,7 @@  import qualified Data.Text.Lazy import qualified Data.Text.Lazy.Builder-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Data.Text.Lazy.Builder.Builder Text where
− src/library/LawfulConversions/Relations/LazyTextBuilderAndUtcTime.hs
@@ -1,15 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.LazyTextBuilderAndUtcTime where--import qualified Data.Text.Lazy.Builder-import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.LazyTextBuilderAndString ()-import LawfulConversions.Relations.StringAndUtcTime ()---- | Implements ISO-8601.-instance IsSome Data.Text.Lazy.Builder.Builder UTCTime where-  to = fromString . to-  maybeFrom = maybeFrom @String . to
− src/library/LawfulConversions/Relations/LazyTextBuilderAndUuid.hs
@@ -1,13 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.LazyTextBuilderAndUuid where--import qualified Data.Text.Lazy-import qualified Data.Text.Lazy.Builder-import qualified Data.UUID.Types-import LawfulConversions.Classes-import LawfulConversions.Prelude--instance IsSome Data.Text.Lazy.Builder.Builder UUID where-  to = Data.Text.Lazy.Builder.fromText . Data.UUID.Types.toText-  maybeFrom = Data.UUID.Types.fromText . Data.Text.Lazy.toStrict . Data.Text.Lazy.Builder.toLazyText
src/library/LawfulConversions/Relations/ListAndSeq.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.ListAndSeq where  import qualified Data.Sequence-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome [a] (Seq a) where
src/library/LawfulConversions/Relations/ShortByteStringAndTextArray.hs view
@@ -7,7 +7,7 @@  import qualified Data.ByteString.Short import qualified Data.Text.Array-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import qualified LawfulConversions.TextCompat.Array 
src/library/LawfulConversions/Relations/ShortByteStringAndWord8List.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.ShortByteStringAndWord8List where  import qualified Data.ByteString.Short-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import LawfulConversions.Relations.ByteArrayAndShortByteString () 
src/library/LawfulConversions/Relations/StrictTextBuilderAndString.hs view
@@ -6,7 +6,7 @@ #if MIN_VERSION_text(2,1,2)  import qualified Data.Text.Encoding-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Relations.StringAndText () import LawfulConversions.Prelude @@ -15,12 +15,12 @@   maybeFrom = fmap Data.Text.Encoding.textToStrictBuilder . maybeFrom  instance IsMany String Data.Text.Encoding.StrictTextBuilder where-  from =  Data.Text.Encoding.textToStrictBuilder . from+  onfrom =  Data.Text.Encoding.textToStrictBuilder . onfrom  #elif MIN_VERSION_text(2,0,2)  import qualified Data.Text.Encoding-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Relations.StringAndText () import LawfulConversions.Prelude @@ -29,6 +29,6 @@   maybeFrom = fmap Data.Text.Encoding.textToStrictBuilder . maybeFrom  instance IsMany String Data.Text.Encoding.StrictBuilder where-  from =  Data.Text.Encoding.textToStrictBuilder . from+  onfrom =  Data.Text.Encoding.textToStrictBuilder . onfrom  #endif
src/library/LawfulConversions/Relations/StrictTextBuilderAndText.hs view
@@ -6,7 +6,7 @@ #if MIN_VERSION_text(2,1,2)  import qualified Data.Text.Encoding-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Text Data.Text.Encoding.StrictTextBuilder where@@ -26,7 +26,7 @@ #elif MIN_VERSION_text(2,0,2)  import qualified Data.Text.Encoding-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome Text Data.Text.Encoding.StrictBuilder where
− src/library/LawfulConversions/Relations/StrictTextBuilderAndUtcTime.hs
@@ -1,36 +0,0 @@-{-# LANGUAGE CPP #-}-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.StrictTextBuilderAndUtcTime where--#if MIN_VERSION_text(2,1,2)--import qualified Data.Text.Encoding-import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.StrictTextBuilderAndString ()-import LawfulConversions.Relations.StringAndText ()-import LawfulConversions.Relations.StringAndUtcTime ()---- | Implements ISO-8601.-instance IsSome Data.Text.Encoding.StrictTextBuilder UTCTime where-  to = from . to @String-  maybeFrom = maybeFrom @String . to--#elif MIN_VERSION_text(2,0,2)--import qualified Data.Text.Encoding-import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.StrictTextBuilderAndString ()-import LawfulConversions.Relations.StringAndText ()-import LawfulConversions.Relations.StringAndUtcTime ()---- | Implements ISO-8601.-instance IsSome Data.Text.Encoding.StrictBuilder UTCTime where-  to = from . to @String-  maybeFrom = maybeFrom @String . to--#endif
− src/library/LawfulConversions/Relations/StrictTextBuilderAndUuid.hs
@@ -1,28 +0,0 @@-{-# LANGUAGE CPP #-}-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.StrictTextBuilderAndUuid where--#if MIN_VERSION_text(2,1,2)--import qualified Data.UUID.Types-import qualified Data.Text.Encoding-import LawfulConversions.Classes-import LawfulConversions.Prelude--instance IsSome Data.Text.Encoding.StrictTextBuilder UUID where-  to = Data.Text.Encoding.textToStrictBuilder . Data.UUID.Types.toText-  maybeFrom = Data.UUID.Types.fromText . Data.Text.Encoding.strictBuilderToText--#elif MIN_VERSION_text(2,0,2)--import qualified Data.UUID.Types-import qualified Data.Text.Encoding-import LawfulConversions.Classes-import LawfulConversions.Prelude--instance IsSome Data.Text.Encoding.StrictBuilder UUID where-  to = Data.Text.Encoding.textToStrictBuilder . Data.UUID.Types.toText-  maybeFrom = Data.UUID.Types.fromText . Data.Text.Encoding.strictBuilderToText--#endif
src/library/LawfulConversions/Relations/StringAndText.hs view
@@ -3,7 +3,7 @@ module LawfulConversions.Relations.StringAndText where  import qualified Data.Text as Text-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude  instance IsSome String Text where@@ -16,4 +16,4 @@           else Nothing  instance IsMany String Text where-  from = Text.pack+  onfrom = Text.pack
− src/library/LawfulConversions/Relations/StringAndUtcTime.hs
@@ -1,13 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.StringAndUtcTime where--import Data.Time-import Data.Time.Format.ISO8601-import LawfulConversions.Classes-import LawfulConversions.Prelude---- | Implements ISO-8601.-instance IsSome String UTCTime where-  to = iso8601Show-  maybeFrom = iso8601ParseM
− src/library/LawfulConversions/Relations/StringAndUuid.hs
@@ -1,11 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.StringAndUuid where--import qualified Data.UUID.Types-import LawfulConversions.Classes-import LawfulConversions.Prelude--instance IsSome String UUID where-  to = Data.UUID.Types.toString-  maybeFrom = Data.UUID.Types.fromString
− src/library/LawfulConversions/Relations/TextAndUtcTime.hs
@@ -1,14 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.TextAndUtcTime where--import Data.Time-import LawfulConversions.Classes-import LawfulConversions.Prelude-import LawfulConversions.Relations.StringAndText ()-import LawfulConversions.Relations.StringAndUtcTime ()---- | Implements ISO-8601.-instance IsSome Text UTCTime where-  to = fromString . to-  maybeFrom = maybeFrom @String . to
− src/library/LawfulConversions/Relations/TextAndUuid.hs
@@ -1,11 +0,0 @@-{-# OPTIONS_GHC -Wno-orphans #-}--module LawfulConversions.Relations.TextAndUuid where--import qualified Data.UUID.Types as Uuid-import LawfulConversions.Classes-import LawfulConversions.Prelude--instance IsSome Text UUID where-  to = Uuid.toText-  maybeFrom = Uuid.fromText
src/library/LawfulConversions/Relations/TextArrayAndWord8List.hs view
@@ -7,7 +7,7 @@  import qualified Data.ByteString.Short import qualified Data.Text.Array-import LawfulConversions.Classes+import LawfulConversions.Algebra import LawfulConversions.Prelude import qualified LawfulConversions.TextCompat.Array 
+ src/library/LawfulConversions/Relations/Void.hs view
@@ -0,0 +1,11 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module LawfulConversions.Relations.Void where++import LawfulConversions.Algebra+import LawfulConversions.Prelude++-- | The empty set has no elements, and therefore is vacuously a subset of any set.+instance IsSome a Void where+  to = absurd+  maybeFrom = const Nothing
src/test/Main.hs view
@@ -110,33 +110,12 @@       testIs @Word64 @Int64 Proxy Proxy,       testIs @Word64 @Word64 Proxy Proxy,       testIs @Word8 @Int8 Proxy Proxy,-      testIs @Word8 @Word8 Proxy Proxy,-      testIsSome @Data.Text.Lazy.Text @UTCTime Proxy Proxy,-      testIsSome @Data.Text.Lazy.Builder.Builder @UTCTime Proxy Proxy,-      testIsSome @String @UTCTime Proxy Proxy,-      testIsSome @Text @UTCTime Proxy Proxy,-      testIsSome @Data.Text.Lazy.Text @Day Proxy Proxy,-      testIsSome @Data.Text.Lazy.Builder.Builder @Day Proxy Proxy,-      testIsSome @String @Day Proxy Proxy,-      testIsSome @Text @Day Proxy Proxy+      testIs @Word8 @Word8 Proxy Proxy     ]  testIs :: (Is a b, Eq a, Eq b, Arbitrary a, Show a, Arbitrary b, Show b, Typeable a, Typeable b) => Proxy a -> Proxy b -> TestTree testIs superp subp =   isProperties superp subp-    & fmap (uncurry testProperty)-    & testGroup groupName-  where-    groupName =-      mconcat-        [ show (typeOf (asProxyTypeOf undefined superp)),-          "/",-          show (typeOf (asProxyTypeOf undefined subp))-        ]--testIsSome :: (IsSome a b, Eq a, Eq b, Arbitrary a, Show a, Arbitrary b, Show b, Typeable a, Typeable b) => Proxy a -> Proxy b -> TestTree-testIsSome superp subp =-  isSomeProperties superp subp     & fmap (uncurry testProperty)     & testGroup groupName   where