packages feed

inj 1.0 → 2.0

raw patch · 7 files changed

+590/−67 lines, 7 filesdep +basesetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: base

API changes (from Hackage documentation)

- Inj: class Inj p a
- Inj: inj :: (Inj p a, (p ~ a)) => p -> a
+ Control.Inj: ($dminj) :: (Inj p a, p ~ a) => p -> a
+ Control.Inj: class Inj p a
+ Control.Inj: inj :: Inj p a => p -> a
+ Control.Inj: instance (Control.Inj.DecideFn p GHC.Types.~ Control.Inj.Decision_Map, p GHC.Types.~ (r -> p'), Control.Inj.Inj p' a) => Control.Inj.InjFn Control.Inj.Decision_Map p r a
+ Control.Inj: instance (Control.Inj.DecideFn p GHC.Types.~ Control.Inj.Decision_Wrap, Control.Inj.Inj p a) => Control.Inj.InjFn Control.Inj.Decision_Wrap p s a
+ Control.Inj: instance (Control.Inj.DecideIO p GHC.Types.~ Control.Inj.Decision_Map, p GHC.Types.~ GHC.Types.IO p', Control.Inj.Inj p' a) => Control.Inj.InjIO Control.Inj.Decision_Map p a
+ Control.Inj: instance (Control.Inj.DecideIO p GHC.Types.~ Control.Inj.Decision_Wrap, Control.Inj.Inj p a) => Control.Inj.InjIO Control.Inj.Decision_Wrap p a
+ Control.Inj: instance (Control.Inj.DecideIdentity p GHC.Types.~ Control.Inj.Decision_Map, p GHC.Types.~ GHC.Internal.Data.Functor.Identity.Identity p', Control.Inj.Inj p' a) => Control.Inj.InjIdentity Control.Inj.Decision_Map p a
+ Control.Inj: instance (Control.Inj.DecideIdentity p GHC.Types.~ Control.Inj.Decision_Wrap, Control.Inj.Inj p a) => Control.Inj.InjIdentity Control.Inj.Decision_Wrap p a
+ Control.Inj: instance (Control.Inj.DecideList p GHC.Types.~ Control.Inj.Decision_Map, p GHC.Types.~ [p'], Control.Inj.Inj p' a) => Control.Inj.InjList Control.Inj.Decision_Map p a
+ Control.Inj: instance (Control.Inj.DecideList p GHC.Types.~ Control.Inj.Decision_Wrap, Control.Inj.Inj p a) => Control.Inj.InjList Control.Inj.Decision_Wrap p a
+ Control.Inj: instance (Control.Inj.DecideMaybe p GHC.Types.~ Control.Inj.Decision_Map, p GHC.Types.~ GHC.Internal.Maybe.Maybe p', Control.Inj.Inj p' a) => Control.Inj.InjMaybe Control.Inj.Decision_Map p a
+ Control.Inj: instance (Control.Inj.DecideMaybe p GHC.Types.~ Control.Inj.Decision_Wrap, Control.Inj.Inj p a) => Control.Inj.InjMaybe Control.Inj.Decision_Wrap p a
+ Control.Inj: instance (Control.Inj.DecideNonEmpty p GHC.Types.~ Control.Inj.Decision_Map, p GHC.Types.~ GHC.Internal.Base.NonEmpty p', Control.Inj.Inj p' a) => Control.Inj.InjNonEmpty Control.Inj.Decision_Map p a
+ Control.Inj: instance (Control.Inj.DecideNonEmpty p GHC.Types.~ Control.Inj.Decision_Wrap, Control.Inj.Inj p a) => Control.Inj.InjNonEmpty Control.Inj.Decision_Wrap p a
+ Control.Inj: instance (Control.Inj.DecideST p GHC.Types.~ Control.Inj.Decision_Map, p GHC.Types.~ GHC.Internal.ST.ST s p', Control.Inj.Inj p' a) => Control.Inj.InjST Control.Inj.Decision_Map p s a
+ Control.Inj: instance (Control.Inj.DecideST p GHC.Types.~ Control.Inj.Decision_Wrap, Control.Inj.Inj p a) => Control.Inj.InjST Control.Inj.Decision_Wrap p s a
+ Control.Inj: instance (Control.Inj.DecideSTM p GHC.Types.~ Control.Inj.Decision_Map, p GHC.Types.~ GHC.Internal.Conc.Sync.STM p', Control.Inj.Inj p' a) => Control.Inj.InjSTM Control.Inj.Decision_Map p a
+ Control.Inj: instance (Control.Inj.DecideSTM p GHC.Types.~ Control.Inj.Decision_Wrap, Control.Inj.Inj p a) => Control.Inj.InjSTM Control.Inj.Decision_Wrap p a
+ Control.Inj: instance (Control.Inj.DecideZipList p GHC.Types.~ Control.Inj.Decision_Map, p GHC.Types.~ GHC.Internal.Functor.ZipList.ZipList p', Control.Inj.Inj p' a) => Control.Inj.InjZipList Control.Inj.Decision_Map p a
+ Control.Inj: instance (Control.Inj.DecideZipList p GHC.Types.~ Control.Inj.Decision_Wrap, Control.Inj.Inj p a) => Control.Inj.InjZipList Control.Inj.Decision_Wrap p a
+ Control.Inj: instance (Data.Fixed.HasResolution res, GHC.Internal.Real.Real p) => Control.Inj.Inj p (Data.Fixed.Fixed res)
+ Control.Inj: instance (GHC.Internal.Num.Num a, Control.Inj.Inj p a) => Control.Inj.Inj p (Data.Complex.Complex a)
+ Control.Inj: instance (GHC.Internal.Real.Integral a, GHC.Internal.Real.Real p) => Control.Inj.Inj p (GHC.Internal.Real.Ratio a)
+ Control.Inj: instance (p GHC.Types.~ ()) => Control.Inj.Inj p ()
+ Control.Inj: instance (p GHC.Types.~ GHC.Internal.Data.Proxy.Proxy t') => Control.Inj.Inj p (GHC.Internal.Data.Proxy.Proxy t)
+ Control.Inj: instance (p GHC.Types.~ GHC.Types.Bool) => Control.Inj.Inj p GHC.Types.Bool
+ Control.Inj: instance (p GHC.Types.~ GHC.Types.Char) => Control.Inj.Inj p GHC.Types.Char
+ Control.Inj: instance (p GHC.Types.~ GHC.Types.Ordering) => Control.Inj.Inj p GHC.Types.Ordering
+ Control.Inj: instance (t GHC.Types.~ (pa, pb), Control.Inj.Inj pa a, Control.Inj.Inj pb b) => Control.Inj.Inj t (a, b)
+ Control.Inj: instance (t GHC.Types.~ (pa, pb, pc), Control.Inj.Inj pa a, Control.Inj.Inj pb b, Control.Inj.Inj pc c) => Control.Inj.Inj t (a, b, c)
+ Control.Inj: instance (t GHC.Types.~ (pa, pb, pc, pd), Control.Inj.Inj pa a, Control.Inj.Inj pb b, Control.Inj.Inj pc c, Control.Inj.Inj pd d) => Control.Inj.Inj t (a, b, c, d)
+ Control.Inj: instance (t GHC.Types.~ GHC.Internal.Data.Either.Either pa pb, Control.Inj.Inj pa a, Control.Inj.Inj pb b) => Control.Inj.Inj t (GHC.Internal.Data.Either.Either a b)
+ Control.Inj: instance (t GHC.Types.~ GHC.Internal.Data.Functor.Const.Const pa pb, Control.Inj.Inj pa a) => Control.Inj.Inj t (GHC.Internal.Data.Functor.Const.Const a b)
+ Control.Inj: instance Control.Inj.Inj p (f (g a)) => Control.Inj.Inj p ((GHC.Internal.Generics.:.:) f g a)
+ Control.Inj: instance Control.Inj.Inj p (f (g a)) => Control.Inj.Inj p (Data.Functor.Compose.Compose f g a)
+ Control.Inj: instance Control.Inj.Inj p (f a) => Control.Inj.Inj p (GHC.Internal.Generics.M1 i c f a)
+ Control.Inj: instance Control.Inj.Inj p (f a) => Control.Inj.Inj p (GHC.Internal.Generics.Rec1 f a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (Data.Semigroup.First a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (Data.Semigroup.Last a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (Data.Semigroup.Max a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (Data.Semigroup.Min a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Data.Monoid.First a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Data.Monoid.Last a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Data.Ord.Down a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Data.Semigroup.Internal.Dual a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Data.Semigroup.Internal.Product a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Data.Semigroup.Internal.Sum a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Generics.K1 i a x)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Generics.Par1 a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Text.ParserCombinators.ReadP.ReadP a)
+ Control.Inj: instance Control.Inj.Inj p a => Control.Inj.Inj p (GHC.Internal.Text.ParserCombinators.ReadPrec.ReadPrec a)
+ Control.Inj: instance Control.Inj.InjFn (Control.Inj.DecideFn p) p r a => Control.Inj.Inj p (r -> a)
+ Control.Inj: instance Control.Inj.InjIO (Control.Inj.DecideIO p) p a => Control.Inj.Inj p (GHC.Types.IO a)
+ Control.Inj: instance Control.Inj.InjIdentity (Control.Inj.DecideIdentity p) p a => Control.Inj.Inj p (GHC.Internal.Data.Functor.Identity.Identity a)
+ Control.Inj: instance Control.Inj.InjList (Control.Inj.DecideList p) p a => Control.Inj.Inj p [a]
+ Control.Inj: instance Control.Inj.InjMaybe (Control.Inj.DecideMaybe p) p a => Control.Inj.Inj p (GHC.Internal.Maybe.Maybe a)
+ Control.Inj: instance Control.Inj.InjNonEmpty (Control.Inj.DecideNonEmpty p) p a => Control.Inj.Inj p (GHC.Internal.Base.NonEmpty a)
+ Control.Inj: instance Control.Inj.InjST (Control.Inj.DecideST p) p s a => Control.Inj.Inj p (GHC.Internal.ST.ST s a)
+ Control.Inj: instance Control.Inj.InjSTM (Control.Inj.DecideSTM p) p a => Control.Inj.Inj p (GHC.Internal.Conc.Sync.STM a)
+ Control.Inj: instance Control.Inj.InjZipList (Control.Inj.DecideZipList p) p a => Control.Inj.Inj p (GHC.Internal.Functor.ZipList.ZipList a)
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Foreign.Ptr.IntPtr
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Foreign.Ptr.WordPtr
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Int.Int16
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Int.Int32
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Int.Int64
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Int.Int8
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Word.Word16
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Word.Word32
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Word.Word64
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Internal.Word.Word8
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Num.Integer.Integer
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Num.Natural.Natural
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Types.Int
+ Control.Inj: instance GHC.Internal.Real.Integral p => Control.Inj.Inj p GHC.Types.Word
+ Control.Inj: instance GHC.Internal.Real.Real p => Control.Inj.Inj p GHC.Types.Double
+ Control.Inj: instance GHC.Internal.Real.Real p => Control.Inj.Inj p GHC.Types.Float

Files

+ CHANGELOG.md view
@@ -0,0 +1,18 @@+# Changelog++## 2.0++* Merged `inj-base` into `inj`. The instances for `base` types are no longer+  orphans and no longer require a separate package.+* Renamed the `Inj` module to `Control.Inj`. Users of `inj-1.0` should update+  their imports from `Inj` to `Control.Inj`; users of `inj-base-0.2` should+  replace `Inj.Base` with `Control.Inj`.+* Removed the instance for `Data.Semigroup.Option`, which no longer exists in+  `base`.+* Added the missing identity instance for `Char`, so that `inj 'a' :: String`+  and similar now work.+* Changed the license from `PublicDomain` to `BSD-3-Clause`.++## 1.0++* Initial release.
− Inj.hs
@@ -1,60 +0,0 @@-{- |--An injection is a function that never maps distinct elements of the domain to-the same element of the codomain. For example, @(\\x -> x + 1)@ is an injection,-but @(\\x -> min x 0)@ is not.--Injections can be used to construct nested structures from singleton elements.---}--{-# LANGUAGE NoImplicitPrelude,-             DefaultSignatures,-             MultiParamTypeClasses,-             TypeFamilies #-}--module Inj (Inj(..)) where---- | Inject @p@ into @a@.------ By convention, the instances of @Inj@ never match on @p@ and always match on--- @a@. This guarantees that the users will not encounter overlapping instances.-class Inj p a where-  -- | Inject @p@ into @a@.-  inj :: p -> a--  default inj :: (p ~ a) => p -> a-  inj = \x -> x---- @instance Inj a a@ is tempting to define. Unfortunately, it does not work--- as well as one might hope. For instance, consider a type like this:------ @--- data Shape x = Circle | Rectangle | Other x---   deriving Functor--- @------ If we want to write @inj Circle@, then we get an ambiguity error:------ @---    * Could not deduce (Inj (Shape x0) (Shape x))---        arising from a use of `inj'--- @------ That is because @Inj a a@ for @Shape x@ is equivalent to------ @instance Inj (Shape x) (Shape x)@------ but for good type inference we want------ @instance (x1 ~ x2) => Inj (Shape x1) (Shape x2)@------ Furthermore, we can take advantage of @Shape@ being a functor and--- define an even better instance:------ @--- instance Inj a b => Inj (Shape a) (Shape b) where---   inj = fmap inj--- @------ Unfortunately, both of the better instances are overlapping with @Inj a a@.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2018, Vladislav Zavialov++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Vladislav Zavialov nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,39 @@+# inj++A class for injective (one-to-one) functions.++An injection is a function that never maps distinct elements of the domain to+the same element of the codomain. For example, `\x -> x + 1` is an injection,+but `\x -> min x 0` is not.++```haskell+class Inj p a where+  inj :: p -> a+```++The instances compose, so `inj` can construct nested structures from singleton+elements, wrapping and converting as needed:++```haskell+ghci> inj 'a' :: Maybe [Char]+Just "a"++ghci> inj True :: Maybe [Bool]+Just [True]++ghci> inj (5 :: Int) :: Maybe Double+Just 5.0++ghci> inj [1, 2, 3 :: Int] :: [Double]+[1.0,2.0,3.0]++ghci> inj (True, 2 :: Int) :: (Maybe Bool, [Double])+(Just True,[2.0])+```++By convention, the instances of `Inj` never match on `p` and always match on+`a`. This guarantees that users will not encounter overlapping instances.++Instances for `base` types are provided by this package. Before version 2.0+they lived in a separate `inj-base` package; see the [changelog](CHANGELOG.md)+for migration notes.
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
inj.cabal view
@@ -1,14 +1,32 @@+cabal-version:       3.0 name:                inj-version:             1.0+version:             2.0 synopsis:            A class for injective (one-to-one) functions-license:             PublicDomain+description:+  An injection is a function that never maps distinct elements of the domain+  to the same element of the codomain. For example, @(\\x -> x + 1)@ is an+  injection, but @(\\x -> min x 0)@ is not.+  .+  This package provides the @Inj@ class, whose instances can be composed to+  construct nested structures from singleton elements.+license:             BSD-3-Clause+license-file:        LICENSE author:              Vladislav Zavialov maintainer:          Vladislav Zavialov <vlad.z.4096@gmail.com>-category:            Data+category:            Control build-type:          Simple-cabal-version:       >=1.10+tested-with:         GHC ==9.2.8, GHC ==9.4.8, GHC ==9.6.7, GHC ==9.8.4,+                     GHC ==9.10.3, GHC ==9.12.4, GHC ==9.14.1+extra-doc-files:     README.md+                     CHANGELOG.md +source-repository head+  type: git+  location: https://github.com/int-index/inj.git+ library-  exposed-modules:     Inj+  exposed-modules:     Control.Inj+  build-depends:       base >=4.16 && <5+  hs-source-dirs:      src   default-language:    Haskell2010   ghc-options:         -Wall
+ src/Control/Inj.hs view
@@ -0,0 +1,480 @@+{- |++An injection is a function that never maps distinct elements of the domain to+the same element of the codomain. For example, @(\\x -> x + 1)@ is an injection,+but @(\\x -> min x 0)@ is not.++Injections can be used to construct nested structures from singleton elements.++-}++{-# LANGUAGE DefaultSignatures,+             FlexibleContexts,+             FlexibleInstances,+             MultiParamTypeClasses,+             ScopedTypeVariables,+             TypeFamilies,+             TypeOperators,+             UndecidableInstances+#-}++module Control.Inj (Inj(..)) where++import Control.Applicative+import Control.Exception hiding (TypeError)+import Control.Monad.ST+import Data.Bifunctor+import Data.Complex+import Data.Fixed+import Data.Functor.Compose+import Data.Functor.Identity+import Data.Int+import Data.List.NonEmpty+import Data.Monoid+import Data.Ord+import Data.Proxy+import Data.Ratio+import Data.Semigroup+import Data.Word+import Foreign.Ptr+import GHC.Conc+import GHC.Generics+import Numeric.Natural+import Text.ParserCombinators.ReadP+import Text.ParserCombinators.ReadPrec++-- | Inject @p@ into @a@.+--+-- By convention, the instances of @Inj@ never match on @p@ and always match on+-- @a@. This guarantees that the users will not encounter overlapping instances.+class Inj p a where+  -- | Inject @p@ into @a@.+  inj :: p -> a++  default inj :: (p ~ a) => p -> a+  inj = \x -> x++-- @instance Inj a a@ is tempting to define. Unfortunately, it does not work+-- as well as one might hope. For instance, consider a type like this:+--+-- @+-- data Shape x = Circle | Rectangle | Other x+-- @+--+-- If we want to write @inj Circle@, then we get an ambiguity error:+--+-- @+--    * Could not deduce (Inj (Shape x0) (Shape x))+--        arising from a use of `inj'+-- @+--+-- That is because @Inj a a@ for @Shape x@ is equivalent to+--+-- @instance Inj (Shape x) (Shape x)@+--+-- but for good type inference we want+--+-- @instance (p ~ Shape x) => Inj p (Shape x)@+--+-- Unfortunately, this instance can't be used in the presence of @Inj a a@+-- due to overlap.++--------------------------------------------------------------------------------+-- Identity injections+--------------------------------------------------------------------------------++instance p ~ () => Inj p ()+instance p ~ Bool => Inj p Bool+instance p ~ Char => Inj p Char+instance p ~ Ordering => Inj p Ordering++instance p ~ Proxy t' => Inj p (Proxy t) where+  inj Proxy = Proxy++--------------------------------------------------------------------------------+-- Decision procedures for ambiguous injections+--------------------------------------------------------------------------------++data Decision_Wrap++data Decision_Map++type family DecideMaybe p where+  DecideMaybe (Maybe p) = Decision_Map+  DecideMaybe p = Decision_Wrap++class d ~ DecideMaybe p => InjMaybe d p a where+  injMaybe :: p -> Maybe a++instance InjMaybe (DecideMaybe p) p a => Inj p (Maybe a) where+  inj = injMaybe++type family DecideList p where+  DecideList [p] = Decision_Map+  DecideList p = Decision_Wrap++class d ~ DecideList p => InjList d p a where+  injList :: p -> [a]++instance InjList (DecideList p) p a => Inj p [a] where+  inj = injList++type family DecideNonEmpty p where+  DecideNonEmpty (NonEmpty p) = Decision_Map+  DecideNonEmpty p = Decision_Wrap++class d ~ DecideNonEmpty p => InjNonEmpty d p a where+  injNonEmpty :: p -> NonEmpty a++instance InjNonEmpty (DecideNonEmpty p) p a => Inj p (NonEmpty a) where+  inj = injNonEmpty++type family DecideIO p where+  DecideIO (IO p) = Decision_Map+  DecideIO p = Decision_Wrap++class d ~ DecideIO p => InjIO d p a where+  injIO :: p -> IO a++instance InjIO (DecideIO p) p a => Inj p (IO a) where+  inj = injIO++type family DecideSTM p where+  DecideSTM (STM p) = Decision_Map+  DecideSTM p = Decision_Wrap++class d ~ DecideSTM p => InjSTM d p a where+  injSTM :: p -> STM a++instance InjSTM (DecideSTM p) p a => Inj p (STM a) where+  inj = injSTM++type family DecideIdentity p where+  DecideIdentity (Identity p) = Decision_Map+  DecideIdentity p = Decision_Wrap++class d ~ DecideIdentity p => InjIdentity d p a where+  injIdentity :: p -> Identity a++instance InjIdentity (DecideIdentity p) p a => Inj p (Identity a) where+  inj = injIdentity++type family DecideZipList p where+  DecideZipList (ZipList p) = Decision_Map+  DecideZipList p = Decision_Wrap++class d ~ DecideZipList p => InjZipList d p a where+  injZipList :: p -> ZipList a++instance InjZipList (DecideZipList p) p a => Inj p (ZipList a) where+  inj = injZipList++type family DecideST p where+  DecideST (ST s p) = Decision_Map+  DecideST p = Decision_Wrap++class d ~ DecideST p => InjST d p s a where+  injST :: p -> ST s a++instance InjST (DecideST p) p s a => Inj p (ST s a) where+  inj = injST++type family DecideFn p where+  DecideFn (r -> p) = Decision_Map+  DecideFn p = Decision_Wrap++class d ~ DecideFn p => InjFn d p r a where+  injFn :: p -> r -> a++instance InjFn (DecideFn p) p r a => Inj p (r -> a) where+  inj = injFn++--------------------------------------------------------------------------------+-- 'fromIntegral' is an injection from any @Integral p@ to any @Num a@.+--------------------------------------------------------------------------------++instance Integral p => Inj p Integer where+  inj = toInteger++-- | Throws 'Underflow'.+instance Integral p => Inj p Natural where+  inj = fromIntegral++fromIntegralBounded ::+  forall p a. (Integral a, Bounded a) => Integral p => p -> a+fromIntegralBounded p+  | p' < toInteger (minBound :: a) = throw Underflow+  | p' > toInteger (maxBound :: a) = throw Overflow+  | otherwise = fromInteger p'+  where+    p' = toInteger p++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Int where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Int8 where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Int16 where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Int32 where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Int64 where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Word where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Word8 where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Word16 where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Word32 where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p Word64 where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p IntPtr where+  inj = fromIntegralBounded++-- | Throws 'Underflow' and 'Overflow'.+instance Integral p => Inj p WordPtr where+  inj = fromIntegralBounded++--------------------------------------------------------------------------------+-- 'realToFrac' is an injection from any @Real p@ to any @Fractional a@.+--------------------------------------------------------------------------------++instance (Integral a, Real p) => Inj p (Ratio a) where+  inj = realToFrac++-- | Throws 'LossOfPrecision'.+instance (HasResolution res, Real p) => Inj p (Fixed res) where+  inj p+    | denominator i == 1 = MkFixed (numerator i)+    | otherwise = throw LossOfPrecision+    where+      i = toRational p * toRational res+      res = resolution (Proxy :: Proxy res)++-- | Injective only if the number is representable as 'Float'.+instance Real p => Inj p Float where+  inj = realToFrac++-- | Injective only if the number is representable as 'Double'.+instance Real p => Inj p Double where+  inj = realToFrac++instance (Num a, Inj p a) => Inj p (Complex a) where+  inj p = inj p :+ 0++--------------------------------------------------------------------------------+-- 'pure' is often an injection into @Applicative f@.+--------------------------------------------------------------------------------++instance+    (DecideList p ~ Decision_Wrap, Inj p a) =>+    InjList Decision_Wrap p a+  where+    injList = pure . inj++instance+    (DecideMaybe p ~ Decision_Wrap, Inj p a) =>+    InjMaybe Decision_Wrap p a+  where+    injMaybe = pure . inj++instance+    (DecideNonEmpty p ~ Decision_Wrap, Inj p a) =>+    InjNonEmpty Decision_Wrap p a+  where+    injNonEmpty = pure . inj++instance+    (DecideIO p ~ Decision_Wrap, Inj p a) =>+    InjIO Decision_Wrap p a+  where+    injIO = pure . inj++instance Inj p a => Inj p (ReadP a) where+  inj = pure . inj++instance Inj p a => Inj p (ReadPrec a) where+  inj = pure . inj++instance Inj p a => Inj p (Down a) where+  inj = pure . inj++instance Inj p a => Inj p (Product a) where+  inj = pure . inj++instance Inj p a => Inj p (Sum a) where+  inj = pure . inj++instance Inj p a => Inj p (Dual a) where+  inj = pure . inj++instance Inj p a => Inj p (Data.Monoid.Last a) where+  inj = pure . inj++instance Inj p a => Inj p (Data.Monoid.First a) where+  inj = pure . inj++instance+    (DecideSTM p ~ Decision_Wrap, Inj p a) =>+    InjSTM Decision_Wrap p a+  where+    injSTM = pure . inj++instance+    (DecideIdentity p ~ Decision_Wrap, Inj p a) =>+    InjIdentity Decision_Wrap p a+  where+    injIdentity = pure . inj++instance+    (DecideZipList p ~ Decision_Wrap, Inj p a) =>+    InjZipList Decision_Wrap p a+  where+    injZipList = pure . inj++instance Inj p a => Inj p (Data.Semigroup.Last a) where+  inj = pure . inj++instance Inj p a => Inj p (Data.Semigroup.First a) where+  inj = pure . inj++instance Inj p a => Inj p (Max a) where+  inj = pure . inj++instance Inj p a => Inj p (Min a) where+  inj = pure . inj++instance+    (DecideST p ~ Decision_Wrap, Inj p a) =>+    InjST Decision_Wrap p s a+  where+    injST = pure . inj++instance+    (DecideFn p ~ Decision_Wrap, Inj p a) =>+    InjFn Decision_Wrap p s a+  where+    injFn = pure . inj++instance Inj p (f (g a)) => Inj p (Compose f g a) where+  inj = Compose . inj++--------------------------------------------------------------------------------+-- 'fmap', 'bimap', etc, can be used to map injections+--------------------------------------------------------------------------------++instance+    (DecideMaybe p ~ Decision_Map, p ~ Maybe p', Inj p' a) =>+    InjMaybe Decision_Map p a+  where+    injMaybe = fmap inj++instance+    (DecideList p ~ Decision_Map, p ~ [p'], Inj p' a) =>+    InjList Decision_Map p a+  where+    injList = fmap inj++instance+    (DecideNonEmpty p ~ Decision_Map, p ~ NonEmpty p', Inj p' a) =>+    InjNonEmpty Decision_Map p a+  where+    injNonEmpty = fmap inj++instance+    (DecideIO p ~ Decision_Map, p ~ IO p', Inj p' a) =>+    InjIO Decision_Map p a+  where+    injIO = fmap inj++instance+    (DecideSTM p ~ Decision_Map, p ~ STM p', Inj p' a) =>+    InjSTM Decision_Map p a+  where+    injSTM = fmap inj++instance+    (DecideIdentity p ~ Decision_Map, p ~ Identity p', Inj p' a) =>+    InjIdentity Decision_Map p a+  where+    injIdentity = fmap inj++instance+    (DecideZipList p ~ Decision_Map, p ~ ZipList p', Inj p' a) =>+    InjZipList Decision_Map p a+  where+    injZipList = fmap inj++instance+    (DecideST p ~ Decision_Map, p ~ ST s p', Inj p' a) =>+    InjST Decision_Map p s a+  where+    injST = fmap inj++instance+    (DecideFn p ~ Decision_Map, p ~ (r -> p'), Inj p' a) =>+    InjFn Decision_Map p r a+  where+    injFn = fmap inj++instance (t ~ (pa, pb), Inj pa a, Inj pb b) => Inj t (a, b) where+  inj = bimap inj inj++instance+    (t ~ (pa, pb, pc), Inj pa a, Inj pb b, Inj pc c) =>+    Inj t (a, b, c)+  where+    inj (pa, pb, pc) = (inj pa, inj pb, inj pc)++instance+    (t ~ (pa, pb, pc, pd), Inj pa a, Inj pb b, Inj pc c, Inj pd d) =>+    Inj t (a, b, c, d)+  where+    inj (pa, pb, pc, pd) = (inj pa, inj pb, inj pc, inj pd)++instance (t ~ Either pa pb, Inj pa a, Inj pb b) => Inj t (Either a b) where+  inj = bimap inj inj++instance (t ~ Const pa pb, Inj pa a) => Inj t (Const a b) where+  inj (Const pa) = Const (inj pa)++--------------------------------------------------------------------------------+-- Generic+--------------------------------------------------------------------------------++instance Inj p (f a) => Inj p (Rec1 f a) where+  inj = Rec1 . inj++instance Inj p (f a) => Inj p (M1 i c f a) where+  inj = M1 . inj++instance Inj p a => Inj p (Par1 a) where+  inj = Par1 . inj++instance Inj p a => Inj p (K1 i a x) where+  inj = K1 . inj++instance Inj p (f (g a)) => Inj p ((:.:) f g a) where+  inj = Comp1 . inj