Cabal revisions of lawful-conversions-0.1.1
Hackage metadata revisions edit the .cabal file after upload; each diff below is one revision.
revision 1
-cabal-version: 3.0-name: lawful-conversions-version: 0.1.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,+cabal-version: 3.0 +name: lawful-conversions +version: 0.1.1 +x-revision: 1 +synopsis: Lawful typeclasses for bidirectional conversion between types +description: + 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 or lossless conversion + + = 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. +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,
revision 2
cabal-version: 3.0 name: lawful-conversions version: 0.1.1 -x-revision: 1 +x-revision: 2 synopsis: Lawful typeclasses for bidirectional conversion between types description: Lawful typeclasses capturing three main patterns of bidirectional mapping. The typeclasses form a layered hierarchy with ascending strictness of laws. - 1. `IsSome`: Smart constructor + 1. `LawfulConversions.IsSome`: Smart constructor - 2. `IsMany`: Lossy conversion + 2. `LawfulConversions.IsMany`: Lossy conversion - 3. `Is`: Isomorphism or lossless conversion + 3. `LawfulConversions.Is`: Isomorphism or lossless conversion = The conversion problem = Conversions - The main part of the API is two functions: 'to' and 'from'. Both + The main part of the API is two functions: 'LawfulConversions.to' and 'LawfulConversions.from'. Both perform a conversion between two types. The main difference between them is in what the first type application parameter specifies. E.g.: > > :t from @Text > from @Text :: IsMany Text b => Text -> b - In other words 'to' and 'from' let you explicitly specify either the source + In other words 'LawfulConversions.to' and 'LawfulConversions.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. @ renderNameAndHeight :: 'Text' -> 'Int' -> 'Text' renderNameAndHeight name height = - 'from' @'Data.Text.Encoding.StrictTextBuilder' $ - "Height of " <> 'to' name <> " is " <> 'to' (show height) + 'LawfulConversions.from' @'Data.Text.Encoding.StrictTextBuilder' $ + "Height of " <> 'LawfulConversions.to' name <> " is " <> 'LawfulConversions.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 + 'LawfulConversions.from' @'Data.ByteString.Builder.Builder' $ + 'LawfulConversions.to' a <> 'LawfulConversions.to' b <> 'LawfulConversions.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 library also captures the pattern of smart constructors via the 'LawfulConversions.IsSome' class, which associates a total 'LawfulConversions.to' conversion with its partial inverse 'LawfulConversions.maybeFrom'. This captures the codec relationship between types. E.g.,
revision 3
cabal-version: 3.0 name: lawful-conversions version: 0.1.1 -x-revision: 2 +x-revision: 3 synopsis: Lawful typeclasses for bidirectional conversion between types description: Lawful typeclasses capturing three main patterns of bidirectional mapping. The typeclasses form a layered hierarchy with ascending strictness of laws. - 1. `LawfulConversions.IsSome`: Smart constructor + 1. `IsSome`: Smart constructor - 2. `LawfulConversions.IsMany`: Lossy conversion + 2. `IsMany`: Lossy conversion - 3. `LawfulConversions.Is`: Isomorphism or lossless conversion + 3. `Is`: Isomorphism or lossless conversion = The conversion problem = Conversions - The main part of the API is two functions: 'LawfulConversions.to' and 'LawfulConversions.from'. Both + 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.: > > :t from @Text > from @Text :: IsMany Text b => Text -> b - In other words 'LawfulConversions.to' and 'LawfulConversions.from' let you explicitly specify either the source + 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. @ renderNameAndHeight :: 'Text' -> 'Int' -> 'Text' renderNameAndHeight name height = - 'LawfulConversions.from' @'Data.Text.Encoding.StrictTextBuilder' $ - "Height of " <> 'LawfulConversions.to' name <> " is " <> 'LawfulConversions.to' (show 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 = - 'LawfulConversions.from' @'Data.ByteString.Builder.Builder' $ - 'LawfulConversions.to' a <> 'LawfulConversions.to' b <> 'LawfulConversions.to' 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 'LawfulConversions.IsSome' class, which associates a total 'LawfulConversions.to' conversion with its partial inverse 'LawfulConversions.maybeFrom'. + 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.,
revision 4
cabal-version: 3.0 name: lawful-conversions version: 0.1.1 -x-revision: 3 +x-revision: 4 synopsis: Lawful typeclasses for bidirectional conversion between types description: - Lawful typeclasses capturing three main patterns of bidirectional mapping. The typeclasses form a layered hierarchy with ascending strictness of laws. - - 1. `IsSome`: Smart constructor - + # Summary + + Lawful typeclasses capturing three main patterns of bidirectional mapping. The typeclasses form a layered hierarchy with ascending strictness of laws: + + 1. `IsSome`: Smart constructor pattern + 2. `IsMany`: Lossy conversion - - 3. `Is`: Isomorphism or lossless conversion - - = 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'? - + + 3. `Is`: Isomorphism (lossless conversion) + + # 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? - + + # 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. category: Conversion homepage: https://github.com/nikita-volkov/lawful-conversions bug-reports: https://github.com/nikita-volkov/lawful-conversions/issues
revision 5
cabal-version: 3.0 name: lawful-conversions version: 0.1.1 -x-revision: 4 +x-revision: 5 synopsis: Lawful typeclasses for bidirectional conversion between types description: - # Summary - - Lawful typeclasses capturing three main patterns of bidirectional mapping. The typeclasses form a layered hierarchy with ascending strictness of laws: - - 1. `IsSome`: Smart constructor pattern + = Summary + Lawful typeclasses capturing three patterns of bidirectional mapping and forming a layered hierarchy with an ascending strictness of laws. + + 1. `IsSome`: Smart constructor + 2. `IsMany`: Lossy conversion - - 3. `Is`: Isomorphism (lossless conversion) - - # 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 + + 3. `Is`: Isomorphism or lossless conversion + + = 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 different 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? - + + = 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.