    -- |
    -- = UX
    --
    -- Essentially the whole API is just two functions: 'to' and 'from'. Both
    -- perform a conversion between two types. The only difference between them
    -- is in what the first type application parameter specifies. E.g.:
    --
    -- > toText = to @Text
    --
    -- > fromBuilder = from @Builder
    --
    -- The types are self-evident:
    --
    -- > > :t to @Text
    -- > to @Text :: IsomorphicTo Text b => b -> Text
    --
    -- > > :t from @Builder
    -- > from @Builder :: IsomorphicTo Builder b => Builder -> 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 :: 'Data.ByteString.Short.ShortByteString' -> 'Data.Primitive.ByteArray' -> 'Data.ByteString.Lazy.ByteString' -> [Word8]
    -- combineEncodings a b c =
    --   'from' @'Data.ByteString.Builder.Builder' $
    --     'to' a <> 'to' b <> 'to' c
    -- @
    --
    -- Which is equivalent to:
    --
    -- @
    -- combineEncodings :: 'Data.ByteString.Short.ShortByteString' -> 'Data.Primitive.ByteArray' -> 'Data.ByteString.Lazy.ByteString' -> [Word8]
    -- combineEncodings a b c =
    --   LazyByteString.'Data.ByteString.Lazy.unpack' $
    --     Builder.'Data.ByteString.Builder.toLazyByteString' $
    --       mconcat
    --         [ Builder.'Data.ByteString.Builder.shortByteString' a,
    --           Builder.'Data.ByteString.Builder.shortByteString'
    --             ( let ByteArray.'Data.Primitive.ByteArray.ByteArray' array = b
    --                in ShortByteString.'Data.ByteString.Short.SBS' array
    --             ),
    --           Builder.'Data.ByteString.Builder.lazyByteString' c
    --         ]
    -- @
    module IsomorphismClass
      ( -- * Typeclasses
        IsomorphicTo (..),
        from,

        -- * Optics
        isomorphicToIso,

        -- * Testing
        module IsomorphismClass.Properties,
      )
    where

    import IsomorphismClass.Classes
    import IsomorphismClass.Optics
    import IsomorphismClass.Properties
    import IsomorphismClass.Relations ()