lawful-conversions-0.1.6: Lawful typeclasses for bidirectional conversion between types
Safe HaskellNone
LanguageHaskell2010

LawfulConversions

Description

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

combineEncodings :: ShortByteString -> ByteArray -> [Word8] -> ByteString
combineEncodings a b c =
  from @Builder $
    to a <> to b <> to c
renderNameAndHeight :: Text -> Int -> Text
renderNameAndHeight name height =
  from @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.

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 Texts are not URLs unfortunately.
  • UTCTime, JSON, Email, etc.

Examples

Here's an example of implementing the Smart Constructor pattern.

module Percent (Percent) where

import LawfulConversions

newtype Percent = Percent Double

instance IsSome Double Percent where
  to (Percent double) = double
  maybeFrom double =
    if double < 0 || double > 1
      then Nothing
      else Just (Percent double)

You can also expand upon that and provide a default handling of invalid values effectively providing a lossy canonicalizing conversion (Surjection):

instance IsMany Double Percent where
  from double =
    if double < 0
      then Percent 0
      else if double > 1
        then Percent 1
        else Percent double

However declaring an instance of Is would be incorrect, because this conversion is partial. Namely, while every Percent value can be losslessly transformed into Double, not every Double can be losslessly transformed into Percent.

Synopsis

Typeclasses

class IsSome a b where Source #

Evidence that all values of type b form a subset of all values of type a.

From Wikipedia:

In mathematics, a set A is a subset of a set B if all elements of A are also elements of B; B is then a superset of A. It is possible for A and B to be equal; if they are unequal, then A is a proper subset of B. The relationship of one set being a subset of another is called inclusion (or sometimes containment). A is a subset of B may also be expressed as B includes (or contains) A or A is included (or contained) in B. A k-subset is a subset with k elements.

Laws

to is injective

For every two values of type 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 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 isSomeProperties.

Minimal complete definition

to

Methods

to :: b -> a Source #

Convert a value of a subset type to a superset type.

maybeFrom :: a -> Maybe b Source #

default maybeFrom :: IsSome b a => a -> Maybe b Source #

Requires the presence of IsSome in reverse direction.

Instances

Instances details
IsSome ByteArray Builder Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteStringBuilder

IsSome ByteArray ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndByteString

IsSome ByteArray ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteString

IsSome ByteArray ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndShortByteString

IsSome Builder ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteStringBuilder

IsSome Builder ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder

IsSome Builder ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder

IsSome Builder ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString

IsSome ByteString ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndByteString

IsSome ByteString Builder Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder

IsSome ByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteString

IsSome ByteString ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndShortByteString

IsSome ByteString Text Source #

UTF-8 codec.

Instance details

Defined in LawfulConversions.Relations.ByteStringAndText

IsSome ByteString Text Source #

UTF-8 codec.

Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyText

IsSome ByteString String Source #

UTF-8 codec.

Instance details

Defined in LawfulConversions.Relations.ByteStringAndString

IsSome ByteString ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteString

IsSome ByteString Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder

IsSome ByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteString

IsSome ByteString ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndShortByteString

IsSome ByteString Text Source #

UTF-8 codec.

Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndText

IsSome ByteString Text Source #

UTF-8 codec.

Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndLazyText

IsSome ByteString String Source #

UTF-8 codec.

Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndString

IsSome ShortByteString ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndShortByteString

IsSome ShortByteString Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString

IsSome ShortByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndShortByteString

IsSome ShortByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndShortByteString

IsSome Int16 Word16 Source # 
Instance details

Defined in LawfulConversions.Relations.Int16AndWord16

IsSome Int32 Word32 Source # 
Instance details

Defined in LawfulConversions.Relations.Int32AndWord32

IsSome Int64 Word64 Source # 
Instance details

Defined in LawfulConversions.Relations.Int64AndWord64

IsSome Int8 Word8 Source # 
Instance details

Defined in LawfulConversions.Relations.Int8AndWord8

IsSome Word16 Int16 Source # 
Instance details

Defined in LawfulConversions.Relations.Int16AndWord16

IsSome Word32 Int32 Source # 
Instance details

Defined in LawfulConversions.Relations.Int32AndWord32

IsSome Word64 Int64 Source # 
Instance details

Defined in LawfulConversions.Relations.Int64AndWord64

IsSome Word8 Int8 Source # 
Instance details

Defined in LawfulConversions.Relations.Int8AndWord8

IsSome Text Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndText

IsSome Text Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndText

IsSome Text StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndText

IsSome Text Day Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.DayAndText

IsSome Text UTCTime Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.TextAndUtcTime

IsSome Text UUID Source # 
Instance details

Defined in LawfulConversions.Relations.TextAndUuid

IsSome Builder Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndText

IsSome Builder Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndLazyTextBuilder

IsSome Builder StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder

IsSome Builder Day Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.DayAndLazyTextBuilder

IsSome Builder UTCTime Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndUtcTime

IsSome Builder UUID Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndUuid

IsSome Text Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndText

IsSome Text Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndLazyTextBuilder

IsSome Text StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndStrictTextBuilder

IsSome Text Day Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.DayAndLazyText

IsSome Text UTCTime Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.LazyTextAndUtcTime

IsSome Text UUID Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndUuid

IsSome StrictBuilder Text Source # 
Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndText

IsSome StrictBuilder Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder

IsSome StrictBuilder Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndStrictTextBuilder

IsSome StrictBuilder Day Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.DayAndStrictTextBuilder

IsSome StrictBuilder UTCTime Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndUtcTime

IsSome StrictBuilder UUID Source # 
Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndUuid

IsSome String Text Source # 
Instance details

Defined in LawfulConversions.Relations.StringAndText

IsSome String Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndString

IsSome String Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndString

IsSome String StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndString

IsSome String Day Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.DayAndString

IsSome String UTCTime Source #

Implements ISO-8601.

Instance details

Defined in LawfulConversions.Relations.StringAndUtcTime

IsSome String UUID Source # 
Instance details

Defined in LawfulConversions.Relations.StringAndUuid

IsSome Int Word Source # 
Instance details

Defined in LawfulConversions.Relations.IntAndWord

IsSome Word Int Source # 
Instance details

Defined in LawfulConversions.Relations.IntAndWord

IsSome a Void Source #

The empty set has no elements, and therefore is vacuously a subset of any set.

Instance details

Defined in LawfulConversions.Classes.IsSome

Methods

to :: Void -> a Source #

maybeFrom :: a -> Maybe Void Source #

IsSome a a Source #

Every type is isomorphic to itself.

Instance details

Defined in LawfulConversions.Classes.IsSome

Methods

to :: a -> a Source #

maybeFrom :: a -> Maybe a Source #

IsSome ByteArray [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndWord8List

IsSome Builder [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndWord8List

IsSome ByteString [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndWord8List

IsSome ByteString [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndWord8List

IsSome ShortByteString [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.ShortByteStringAndWord8List

IsSome IntSet (Set Int) Source # 
Instance details

Defined in LawfulConversions.Relations.IntSetAndSetOfInt

IsSome a b => IsSome a (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

to :: ViaIsSome a b -> a Source #

maybeFrom :: a -> Maybe (ViaIsSome a b) Source #

IsSome b (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

to :: ViaIsSome a b -> b Source #

maybeFrom :: b -> Maybe (ViaIsSome a b) Source #

IsSome (Set Int) IntSet Source # 
Instance details

Defined in LawfulConversions.Relations.IntSetAndSetOfInt

IsSome [Word8] ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndWord8List

IsSome [Word8] Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndWord8List

IsSome [Word8] ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndWord8List

IsSome [Word8] ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndWord8List

IsSome [Word8] ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ShortByteStringAndWord8List

IsSome (Seq a) (Vector a) Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndSeq

Methods

to :: Vector a -> Seq a Source #

maybeFrom :: Seq a -> Maybe (Vector a) Source #

IsSome (Seq a) [a] Source # 
Instance details

Defined in LawfulConversions.Relations.ListAndSeq

Methods

to :: [a] -> Seq a Source #

maybeFrom :: Seq a -> Maybe [a] Source #

IsSome (Vector a) (Seq a) Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndSeq

Methods

to :: Seq a -> Vector a Source #

maybeFrom :: Vector a -> Maybe (Seq a) Source #

IsSome (Vector a) [a] Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndList

Methods

to :: [a] -> Vector a Source #

maybeFrom :: Vector a -> Maybe [a] Source #

IsSome [a] (Seq a) Source # 
Instance details

Defined in LawfulConversions.Relations.ListAndSeq

Methods

to :: Seq a -> [a] Source #

maybeFrom :: [a] -> Maybe (Seq a) Source #

IsSome [a] (Vector a) Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndList

Methods

to :: Vector a -> [a] Source #

maybeFrom :: [a] -> Maybe (Vector a) Source #

IsSome (IntMap v) (Map Int v) Source # 
Instance details

Defined in LawfulConversions.Relations.IntMapAndMapOfInt

Methods

to :: Map Int v -> IntMap v Source #

maybeFrom :: IntMap v -> Maybe (Map Int v) Source #

IsSome (ViaIsSome a b) b Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

to :: b -> ViaIsSome a b Source #

maybeFrom :: ViaIsSome a b -> Maybe b Source #

IsSome (Map Int v) (IntMap v) Source # 
Instance details

Defined in LawfulConversions.Relations.IntMapAndMapOfInt

Methods

to :: IntMap v -> Map Int v Source #

maybeFrom :: Map Int v -> Maybe (IntMap v) Source #

class IsSome a b => IsMany a b where Source #

Lossy or canonicalizing conversion. Captures mappings from multiple alternative inputs into one output.

E.g.,

  • ByteString can be decoded into Text with UTF-8 leniently, replacing the invalid chars with a default char.
  • String has a wider range of supported chars than Text, so some chars get replaced too.

Laws

from is an inverse of to

\b -> b == from (to @a b)

Testing

For testing whether your instances conform to these laws use isManyProperties.

Minimal complete definition

Nothing

Methods

from :: a -> b Source #

Possibly lossy inverse of to. Surjection 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.

default from :: IsSome b a => a -> b Source #

Requires the presence of IsSome in reverse direction.

Instances

Instances details
IsMany ByteArray Builder Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteStringBuilder

IsMany ByteArray ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndByteString

IsMany ByteArray ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteString

IsMany ByteArray ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndShortByteString

IsMany Builder ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteStringBuilder

IsMany Builder ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder

IsMany Builder ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder

IsMany Builder ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString

IsMany ByteString ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndByteString

IsMany ByteString Builder Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder

IsMany ByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteString

IsMany ByteString ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndShortByteString

IsMany ByteString Text Source #

Lenient UTF-8 decoding.

Instance details

Defined in LawfulConversions.Relations.ByteStringAndText

Methods

from :: ByteString -> Text Source #

IsMany ByteString Text Source #

Lenient UTF-8 decoding.

Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyText

Methods

from :: ByteString -> Text Source #

IsMany ByteString String Source #

Lenient UTF-8 decoding.

Instance details

Defined in LawfulConversions.Relations.ByteStringAndString

IsMany ByteString ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteString

IsMany ByteString Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder

IsMany ByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteString

IsMany ByteString ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndShortByteString

IsMany ByteString Text Source #

Lenient UTF-8 decoding.

Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndText

Methods

from :: ByteString -> Text Source #

IsMany ByteString Text Source #

Lenient UTF-8 decoding.

Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndLazyText

Methods

from :: ByteString -> Text Source #

IsMany ByteString String Source #

Lenient UTF-8 decoding.

Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndString

IsMany ShortByteString ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndShortByteString

IsMany ShortByteString Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString

IsMany ShortByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndShortByteString

IsMany ShortByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndShortByteString

IsMany Int16 Word16 Source # 
Instance details

Defined in LawfulConversions.Relations.Int16AndWord16

Methods

from :: Int16 -> Word16 Source #

IsMany Int32 Word32 Source # 
Instance details

Defined in LawfulConversions.Relations.Int32AndWord32

Methods

from :: Int32 -> Word32 Source #

IsMany Int64 Word64 Source # 
Instance details

Defined in LawfulConversions.Relations.Int64AndWord64

Methods

from :: Int64 -> Word64 Source #

IsMany Int8 Word8 Source # 
Instance details

Defined in LawfulConversions.Relations.Int8AndWord8

Methods

from :: Int8 -> Word8 Source #

IsMany Word16 Int16 Source # 
Instance details

Defined in LawfulConversions.Relations.Int16AndWord16

Methods

from :: Word16 -> Int16 Source #

IsMany Word32 Int32 Source # 
Instance details

Defined in LawfulConversions.Relations.Int32AndWord32

Methods

from :: Word32 -> Int32 Source #

IsMany Word64 Int64 Source # 
Instance details

Defined in LawfulConversions.Relations.Int64AndWord64

Methods

from :: Word64 -> Int64 Source #

IsMany Word8 Int8 Source # 
Instance details

Defined in LawfulConversions.Relations.Int8AndWord8

Methods

from :: Word8 -> Int8 Source #

IsMany Text Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndText

Methods

from :: Text -> Builder Source #

IsMany Text Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndText

Methods

from :: Text -> Text Source #

IsMany Text StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndText

IsMany Builder Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndText

Methods

from :: Builder -> Text Source #

IsMany Builder Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndLazyTextBuilder

Methods

from :: Builder -> Text Source #

IsMany Builder StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder

IsMany Text Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndText

Methods

from :: Text -> Text Source #

IsMany Text Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndLazyTextBuilder

Methods

from :: Text -> Builder Source #

IsMany Text StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndStrictTextBuilder

IsMany StrictBuilder Text Source # 
Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndText

IsMany StrictBuilder Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder

IsMany StrictBuilder Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndStrictTextBuilder

IsMany String Text Source # 
Instance details

Defined in LawfulConversions.Relations.StringAndText

Methods

from :: String -> Text Source #

IsMany String Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndString

Methods

from :: String -> Builder Source #

IsMany String Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndString

Methods

from :: String -> Text Source #

IsMany String StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndString

IsMany Int Word Source # 
Instance details

Defined in LawfulConversions.Relations.IntAndWord

Methods

from :: Int -> Word Source #

IsMany Word Int Source # 
Instance details

Defined in LawfulConversions.Relations.IntAndWord

Methods

from :: Word -> Int Source #

IsMany a a Source # 
Instance details

Defined in LawfulConversions.Classes.IsMany

Methods

from :: a -> a Source #

IsMany ByteArray [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndWord8List

Methods

from :: ByteArray -> [Word8] Source #

IsMany Builder [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndWord8List

Methods

from :: Builder -> [Word8] Source #

IsMany ByteString [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndWord8List

Methods

from :: ByteString -> [Word8] Source #

IsMany ByteString [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndWord8List

Methods

from :: ByteString -> [Word8] Source #

IsMany ShortByteString [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.ShortByteStringAndWord8List

IsMany IntSet (Set Int) Source # 
Instance details

Defined in LawfulConversions.Relations.IntSetAndSetOfInt

Methods

from :: IntSet -> Set Int Source #

IsMany b (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

from :: b -> ViaIsSome a b Source #

IsMany (Set Int) IntSet Source # 
Instance details

Defined in LawfulConversions.Relations.IntSetAndSetOfInt

Methods

from :: Set Int -> IntSet Source #

IsMany [Word8] ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndWord8List

Methods

from :: [Word8] -> ByteArray Source #

IsMany [Word8] Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndWord8List

Methods

from :: [Word8] -> Builder Source #

IsMany [Word8] ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndWord8List

Methods

from :: [Word8] -> ByteString Source #

IsMany [Word8] ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndWord8List

Methods

from :: [Word8] -> ByteString Source #

IsMany [Word8] ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ShortByteStringAndWord8List

IsMany (Seq a) (Vector a) Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndSeq

Methods

from :: Seq a -> Vector a Source #

IsMany (Seq a) [a] Source # 
Instance details

Defined in LawfulConversions.Relations.ListAndSeq

Methods

from :: Seq a -> [a] Source #

IsMany (Vector a) (Seq a) Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndSeq

Methods

from :: Vector a -> Seq a Source #

IsMany (Vector a) [a] Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndList

Methods

from :: Vector a -> [a] Source #

IsMany [a] (Seq a) Source # 
Instance details

Defined in LawfulConversions.Relations.ListAndSeq

Methods

from :: [a] -> Seq a Source #

IsMany [a] (Vector a) Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndList

Methods

from :: [a] -> Vector a Source #

IsMany (IntMap v) (Map Int v) Source # 
Instance details

Defined in LawfulConversions.Relations.IntMapAndMapOfInt

Methods

from :: IntMap v -> Map Int v Source #

IsMany (ViaIsSome a b) b Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

from :: ViaIsSome a b -> b Source #

IsMany (Map Int v) (IntMap v) Source # 
Instance details

Defined in LawfulConversions.Relations.IntMapAndMapOfInt

Methods

from :: Map Int v -> IntMap v Source #

class (IsMany a b, Is b a) => Is a b Source #

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 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 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 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.fromStrict

instance IsSome Data.Text.Text Data.Text.Lazy.LazyText where
  to = LazyText.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

Instances

Instances details
Is ByteArray Builder Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteStringBuilder

Is ByteArray ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndByteString

Is ByteArray ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteString

Is ByteArray ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndShortByteString

Is Builder ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteStringBuilder

Is Builder ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder

Is Builder ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder

Is Builder ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString

Is ByteString ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndByteString

Is ByteString Builder Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteStringBuilder

Is ByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteString

Is ByteString ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndShortByteString

Is ByteString ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndLazyByteString

Is ByteString Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndLazyByteStringBuilder

Is ByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndLazyByteString

Is ByteString ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndShortByteString

Is ShortByteString ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndShortByteString

Is ShortByteString Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndShortByteString

Is ShortByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndShortByteString

Is ShortByteString ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndShortByteString

Is Int16 Word16 Source # 
Instance details

Defined in LawfulConversions.Relations.Int16AndWord16

Is Int32 Word32 Source # 
Instance details

Defined in LawfulConversions.Relations.Int32AndWord32

Is Int64 Word64 Source # 
Instance details

Defined in LawfulConversions.Relations.Int64AndWord64

Is Int8 Word8 Source # 
Instance details

Defined in LawfulConversions.Relations.Int8AndWord8

Is Word16 Int16 Source # 
Instance details

Defined in LawfulConversions.Relations.Int16AndWord16

Is Word32 Int32 Source # 
Instance details

Defined in LawfulConversions.Relations.Int32AndWord32

Is Word64 Int64 Source # 
Instance details

Defined in LawfulConversions.Relations.Int64AndWord64

Is Word8 Int8 Source # 
Instance details

Defined in LawfulConversions.Relations.Int8AndWord8

Is Text Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndText

Is Text Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndText

Is Text StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndText

Is Builder Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndText

Is Builder Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndLazyTextBuilder

Is Builder StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder

Is Text Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndText

Is Text Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndLazyTextBuilder

Is Text StrictBuilder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndStrictTextBuilder

Is StrictBuilder Text Source # 
Instance details

Defined in LawfulConversions.Relations.StrictTextBuilderAndText

Is StrictBuilder Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextBuilderAndStrictTextBuilder

Is StrictBuilder Text Source # 
Instance details

Defined in LawfulConversions.Relations.LazyTextAndStrictTextBuilder

Is Int Word Source # 
Instance details

Defined in LawfulConversions.Relations.IntAndWord

Is Word Int Source # 
Instance details

Defined in LawfulConversions.Relations.IntAndWord

Is a a Source #

Any type is isomorphic to itself.

Instance details

Defined in LawfulConversions.Classes.Is

Is ByteArray [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndWord8List

Is Builder [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndWord8List

Is ByteString [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndWord8List

Is ByteString [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndWord8List

Is ShortByteString [Word8] Source # 
Instance details

Defined in LawfulConversions.Relations.ShortByteStringAndWord8List

Is IntSet (Set Int) Source # 
Instance details

Defined in LawfulConversions.Relations.IntSetAndSetOfInt

Is b (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Is (Set Int) IntSet Source # 
Instance details

Defined in LawfulConversions.Relations.IntSetAndSetOfInt

Is [Word8] ByteArray Source # 
Instance details

Defined in LawfulConversions.Relations.ByteArrayAndWord8List

Is [Word8] Builder Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringBuilderAndWord8List

Is [Word8] ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ByteStringAndWord8List

Is [Word8] ByteString Source # 
Instance details

Defined in LawfulConversions.Relations.LazyByteStringAndWord8List

Is [Word8] ShortByteString Source # 
Instance details

Defined in LawfulConversions.Relations.ShortByteStringAndWord8List

Is (Seq a) (Vector a) Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndSeq

Is (Seq a) [a] Source # 
Instance details

Defined in LawfulConversions.Relations.ListAndSeq

Is (Vector a) (Seq a) Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndSeq

Is (Vector a) [a] Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndList

Is [a] (Seq a) Source # 
Instance details

Defined in LawfulConversions.Relations.ListAndSeq

Is [a] (Vector a) Source # 
Instance details

Defined in LawfulConversions.Relations.BoxedVectorAndList

Is (IntMap v) (Map Int v) Source # 
Instance details

Defined in LawfulConversions.Relations.IntMapAndMapOfInt

Is (ViaIsSome a b) b Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Is (Map Int v) (IntMap v) Source # 
Instance details

Defined in LawfulConversions.Relations.IntMapAndMapOfInt

Optics

isSomePrism :: (IsSome a b, Choice p, Applicative f) => p b (f b) -> p a (f a) Source #

Van-Laarhoven-style Prism, compatible with libraries like "lens" and "optics".

isManyIso :: (IsMany a b, Profunctor p, Functor f) => p b (f b) -> p a (f a) Source #

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) Source #

Van-Laarhoven-style Isomorphism, compatible with libraries like "lens" and "optics".

Instance derivation

Proxy data-types useful for deriving various standard instances using the DerivingVia extension.

newtype ViaIsSome a b Source #

Helper for deriving common instances on types which have an instance of IsSome a using the DerivingVia extension.

E.g.,

newtype Percent = Percent Double
  deriving newtype (Show, Eq, Ord)
  deriving (Read, Arbitrary) via (ViaIsSome Double Percent)

instance IsSome Double Percent where
  to (Percent double) = double
  maybeFrom double =
    if double < 0 || double > 1
      then Nothing
      else Just (Percent double)

In the code above all the instances that are able to construct the values of Percent are automatically derived based on the IsSome Double Percent instance. This guarantees that they only construct values that pass thru the checks defined in maybeFrom.

Constructors

ViaIsSome b 

Instances

Instances details
Is b (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

IsMany b (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

from :: b -> ViaIsSome a b Source #

IsSome a b => IsSome a (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

to :: ViaIsSome a b -> a Source #

maybeFrom :: a -> Maybe (ViaIsSome a b) Source #

IsSome b (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

to :: ViaIsSome a b -> b Source #

maybeFrom :: b -> Maybe (ViaIsSome a b) Source #

(IsSome a b, Arbitrary a) => Arbitrary (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

arbitrary :: Gen (ViaIsSome a b) #

shrink :: ViaIsSome a b -> [ViaIsSome a b] #

(IsSome a b, IsString a) => IsString (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

fromString :: String -> ViaIsSome a b #

(IsSome a b, Read a) => Read (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

(IsSome a b, Show a) => Show (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

showsPrec :: Int -> ViaIsSome a b -> ShowS #

show :: ViaIsSome a b -> String #

showList :: [ViaIsSome a b] -> ShowS #

(IsSome a b, Eq a) => Eq (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

(==) :: ViaIsSome a b -> ViaIsSome a b -> Bool #

(/=) :: ViaIsSome a b -> ViaIsSome a b -> Bool #

(IsSome a b, Ord a) => Ord (ViaIsSome a b) Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

compare :: ViaIsSome a b -> ViaIsSome a b -> Ordering #

(<) :: ViaIsSome a b -> ViaIsSome a b -> Bool #

(<=) :: ViaIsSome a b -> ViaIsSome a b -> Bool #

(>) :: ViaIsSome a b -> ViaIsSome a b -> Bool #

(>=) :: ViaIsSome a b -> ViaIsSome a b -> Bool #

max :: ViaIsSome a b -> ViaIsSome a b -> ViaIsSome a b #

min :: ViaIsSome a b -> ViaIsSome a b -> ViaIsSome a b #

Is (ViaIsSome a b) b Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

IsMany (ViaIsSome a b) b Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

from :: ViaIsSome a b -> b Source #

IsSome (ViaIsSome a b) b Source # 
Instance details

Defined in LawfulConversions.Proxies.ViaIsSome

Methods

to :: b -> ViaIsSome a b Source #

maybeFrom :: ViaIsSome a b -> Maybe b Source #

Testing

isSomeProperties :: (IsSome a b, Eq a, Eq b, Show a, Show b, Arbitrary b) => Proxy a -> Proxy b -> [(String, Property)] Source #

Properties testing whether an instance satisfies the laws of IsSome.

The instance is identified via the proxy types that you provide.

E.g., here's how you can integrate it into an Hspec test-suite:

spec = do
  describe "IsSome laws" do
    traverse_
      (uncurry prop)
      (isSomeProperties @Int32 @Int16 Proxy Proxy)

isManyProperties :: (IsMany a b, Eq a, Eq b, Show a, Show b, Arbitrary b) => Proxy a -> Proxy b -> [(String, Property)] Source #

Properties testing whether an instance satisfies the laws of IsMany.

The instance is identified via the proxy types that you provide.

E.g., here's how you can integrate it into an Hspec test-suite:

spec = do
  describe "IsMany laws" do
    traverse_
      (uncurry prop)
      (isManyProperties @String @Text Proxy Proxy)

isProperties :: (Is a b, Eq a, Eq b, Show a, Show b, Arbitrary a, Arbitrary b) => Proxy a -> Proxy b -> [(String, Property)] Source #

Properties testing whether an instance satisfies the laws of Is.

The instance is identified via the proxy types that you provide.

E.g., here's how you can integrate it into an Hspec test-suite:

spec = do
  describe "Is laws" do
    traverse_
      (uncurry prop)
      (isProperties @Int32 @Word32 Proxy Proxy)