Package maintainers and Hackage trustees are allowed to edit certain bits
of package metadata after a release, without uploading a new tarball.
Note that the tarball itself is never changed, just the metadata that is
stored separately. For more information about metadata revisions, please
refer to the
Hackage Metadata Revisions FAQ.
No. |
Time |
User |
SHA256 |
-r5 (lawful-conversions-0.1.1-r5) |
2024-12-04T06:18:42Z |
NikitaVolkov |
176e908155df2de5c499690b16288366fa09970cc2101f7245b096a4a99c82a8
|
|
Changed description
from # 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 (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.
to = 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 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?
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.
|
-r4 (lawful-conversions-0.1.1-r4) |
2024-12-04T06:17:57Z |
NikitaVolkov |
0fc4fc2cfcc69ff336bbe0863eeddb54355859319c1eee0c8ceb5e8a6444e588
|
|
Changed description
from 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.
to # 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 (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.
|
-r3 (lawful-conversions-0.1.1-r3) |
2024-12-04T06:01:16Z |
NikitaVolkov |
85762616fc1acbcf643f9da133ef2f248328fda5d0b65d1bbe9f363df572159b
|
|
Changed description
from 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
2. `LawfulConversions.IsMany`: Lossy conversion
3. `LawfulConversions.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: '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.:
> 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 '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.
== Examples
@
renderNameAndHeight :: 'Text' -> 'Int' -> 'Text'
renderNameAndHeight name 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 =
'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 '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.,
- 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.
to 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.
|
-r2 (lawful-conversions-0.1.1-r2) |
2024-12-04T05:53:37Z |
NikitaVolkov |
9ec257c52deb296660e3cd18bc6aaf76a8d9aaf9fc4c0bca0190b4bfded48212
|
|
Changed description
from 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.
to 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
2. `LawfulConversions.IsMany`: Lossy conversion
3. `LawfulConversions.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: '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.:
> 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 '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.
== Examples
@
renderNameAndHeight :: 'Text' -> 'Int' -> 'Text'
renderNameAndHeight name 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 =
'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 '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.,
- 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.
|
-r1 (lawful-conversions-0.1.1-r1) |
2024-12-04T05:48:29Z |
NikitaVolkov |
122baa7ec69d983da1feadeed66064543376395bed40a5a6ad12fba0e292ba43
|
|
Changed synopsis
from Lawful typeclasses for conversion between types
to Lawful typeclasses for bidirectional conversion between types Changed 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.
|
-r0 (lawful-conversions-0.1.1-r0) |
2024-12-03T02:48:06Z |
NikitaVolkov |
ac36513a8b83e2ed8b8483426abf5b02c8b2e0e454d3502abe2b6bf62f65ad41
|
|
|