packages feed

connections 0.1.0 → 0.2.0

raw patch · 25 files changed

+3608/−3735 lines, 25 filesdep +doctestdep −finite-typelitsdep −transformersdep −universe-basedep ~basenew-component:exe:doctestPVP ok

version bump matches the API change (PVP)

Dependencies added: doctest

Dependencies removed: finite-typelits, transformers, universe-base

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.Connection: (/\) :: Semilattice 'R a => a -> a -> a
- Data.Connection: (\/) :: Semilattice 'L a => a -> a -> a
- Data.Connection: L :: Kan
- Data.Connection: R :: Kan
- Data.Connection: ceiling :: Connection 'L a b => a -> b
- Data.Connection: ceiling1 :: Connection 'L a b => (a -> a) -> b -> b
- Data.Connection: ceiling2 :: Connection 'L a b => (a -> a -> a) -> b -> b -> b
- Data.Connection: choice :: Conn k a b -> Conn k c d -> Conn k (Either a c) (Either b d)
- Data.Connection: class (Preorder a, Preorder b) => Connection k a b
- Data.Connection: conn :: Connection k a b => Conn k a b
- Data.Connection: connL :: Connection 'L a b => ConnL a b
- Data.Connection: connR :: Connection 'R a b => ConnR a b
- Data.Connection: data Conn (k :: Kan) a b
- Data.Connection: data Kan
- Data.Connection: embedL :: Connection 'L a b => b -> a
- Data.Connection: embedR :: Connection 'R a b => b -> a
- Data.Connection: filterL :: Connection 'L a b => a -> b -> Bool
- Data.Connection: filterR :: Connection 'R a b => a -> b -> Bool
- Data.Connection: floor :: Connection 'R a b => a -> b
- Data.Connection: floor1 :: Connection 'R a b => (a -> a) -> b -> b
- Data.Connection: floor2 :: Connection 'R a b => (a -> a -> a) -> b -> b -> b
- Data.Connection: fmapped :: Functor f => Conn k a b -> Conn k (f a) (f b)
- Data.Connection: glb :: Triple (a, a) a => a -> a -> a -> a
- Data.Connection: half :: (Num a, Preorder a) => Trip a b -> a -> Maybe Ordering
- Data.Connection: infixr 5 \/
- Data.Connection: infixr 6 /\
- Data.Connection: lub :: Triple (a, a) a => a -> a -> a -> a
- Data.Connection: maximal :: Extremal 'R a => a
- Data.Connection: maybeL :: Triple () b => Trip (Maybe a) (Either a b)
- Data.Connection: maybeR :: Triple () a => Trip (Maybe b) (Either a b)
- Data.Connection: midpoint :: Fractional a => Trip a b -> a -> a
- Data.Connection: minimal :: Extremal 'L a => a
- Data.Connection: pattern Conn :: (a -> b) -> (b -> a) -> (a -> b) -> Conn k a b
- Data.Connection: pattern ConnL :: (a -> b) -> (b -> a) -> ConnL a b
- Data.Connection: pattern ConnR :: (b -> a) -> (a -> b) -> ConnR a b
- Data.Connection: round :: forall a b. (Num a, Triple a b) => a -> b
- Data.Connection: round1 :: forall a b. (Num a, Triple a b) => (a -> a) -> b -> b
- Data.Connection: round2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b
- Data.Connection: strong :: Conn k a b -> Conn k c d -> Conn k (a, c) (b, d)
- Data.Connection: swapL :: ConnR a b -> ConnL b a
- Data.Connection: swapR :: ConnL a b -> ConnR b a
- Data.Connection: truncate :: (Num a, Triple a b) => a -> b
- Data.Connection: truncate1 :: (Num a, Triple a b) => (a -> a) -> b -> b
- Data.Connection: truncate2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b
- Data.Connection: type ConnDouble k = Connection k Double
- Data.Connection: type ConnExtended k a b = Connection k a (Extended b)
- Data.Connection: type ConnFloat k = Connection k Float
- Data.Connection: type ConnInteger k = Connection k (Maybe Integer)
- Data.Connection: type ConnL = Conn 'L
- Data.Connection: type ConnR = Conn 'R
- Data.Connection: type ConnRational k = Connection k Rational
- Data.Connection: type Extremal k = Connection k ()
- Data.Connection: type Semilattice k a = Connection k (a, a) a
- Data.Connection: type Trip a b = forall k. Conn k a b
- Data.Connection: type Triple a b = (Connection 'L a b, Connection 'R a b)
- Data.Connection.Class: (/\) :: Semilattice 'R a => a -> a -> a
- Data.Connection.Class: (\/) :: Semilattice 'L a => a -> a -> a
- Data.Connection.Class: filterL :: Connection 'L a b => a -> b -> Bool
- Data.Connection.Class: filterR :: Connection 'R a b => a -> b -> Bool
- Data.Connection.Class: fmapped :: Functor f => Conn k a b -> Conn k (f a) (f b)
- Data.Connection.Class: instance (Data.Connection.Class.Connection 'Data.Connection.Conn.L () a, Data.Order.Preorder b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L () (Data.Either.Either a b)
- Data.Connection.Class: instance (Data.Connection.Class.Connection 'Data.Connection.Conn.L (a, a) a, Data.Connection.Class.Connection 'Data.Connection.Conn.L (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.Either.Either a b, Data.Either.Either a b) (Data.Either.Either a b)
- Data.Connection.Class: instance (Data.Connection.Class.Connection 'Data.Connection.Conn.R (a, a) a, Data.Connection.Class.Connection 'Data.Connection.Conn.R (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.Either.Either a b, Data.Either.Either a b) (Data.Either.Either a b)
- Data.Connection.Class: instance (Data.Connection.Class.Triple (a, a) a, Data.Connection.Class.Triple (b, b) b) => Data.Connection.Class.Connection k ((a, b), (a, b)) (a, b)
- Data.Connection.Class: instance (Data.Order.Preorder a, Data.Connection.Class.Connection 'Data.Connection.Conn.R () b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.Either.Either a b)
- Data.Connection.Class: instance (Data.Order.Total a, Data.Connection.Class.Connection 'Data.Connection.Conn.L (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.Map.Internal.Map a b, Data.Map.Internal.Map a b) (Data.Map.Internal.Map a b)
- Data.Connection.Class: instance (Data.Order.Total a, Data.Connection.Class.Connection 'Data.Connection.Conn.R (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.Map.Internal.Map a b, Data.Map.Internal.Map a b) (Data.Map.Internal.Map a b)
- Data.Connection.Class: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.Set.Internal.Set a)
- Data.Connection.Class: instance (Data.Order.Total a, Data.Universe.Class.Finite a, Data.Connection.Class.Connection 'Data.Connection.Conn.R () b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.Map.Internal.Map a b)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple () a) => Data.Connection.Class.Connection k () (Data.Semigroup.Internal.Endo a)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple () b) => Data.Connection.Class.Connection k () (Data.Functor.Contravariant.Op b a)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple () b) => Data.Connection.Class.Connection k () (a -> b)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple (a, a) a) => Data.Connection.Class.Connection k (Data.Semigroup.Internal.Endo a, Data.Semigroup.Internal.Endo a) (Data.Semigroup.Internal.Endo a)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple (b, b) b) => Data.Connection.Class.Connection k (Data.Functor.Contravariant.Op b a, Data.Functor.Contravariant.Op b a) (Data.Functor.Contravariant.Op b a)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple (b, b) b) => Data.Connection.Class.Connection k (a -> b, a -> b) (a -> b)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.IntMap.Internal.IntMap a, Data.IntMap.Internal.IntMap a) (Data.IntMap.Internal.IntMap a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.Order.Extended.Extended a, Data.Order.Extended.Extended a) (Data.Order.Extended.Extended a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.L (GHC.Maybe.Maybe a, GHC.Maybe.Maybe a) (GHC.Maybe.Maybe a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended GHC.Int.Int64)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended GHC.Types.Int)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Int.Int32)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Int.Int64)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Types.Int)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R () a => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.IntMap.Internal.IntMap a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R () a => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (GHC.Maybe.Maybe a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Int.Int16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Int.Int32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Int.Int64
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Int.Int8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Integer.Type.Integer
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Natural.Natural
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Types.Int
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Types.Word
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Word.Word32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Word.Word64
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.IntMap.Internal.IntMap a, Data.IntMap.Internal.IntMap a) (Data.IntMap.Internal.IntMap a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.Order.Extended.Extended a, Data.Order.Extended.Extended a) (Data.Order.Extended.Extended a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe a, GHC.Maybe.Maybe a) (GHC.Maybe.Maybe a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int32 GHC.Int.Int16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int32 GHC.Int.Int8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int64 GHC.Int.Int16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int64 GHC.Int.Int32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int64 GHC.Int.Int8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Integer.Type.Integer
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Types.Word
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Word.Word32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Word.Word64
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word16 GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word32 GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word32 GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word64 GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word64 GHC.Word.Word32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word64 GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection k () Data.IntSet.Internal.IntSet
- Data.Connection.Class: instance Data.Connection.Class.Connection k (Data.Finite.Internal.Finite n, Data.Finite.Internal.Finite n) (Data.Finite.Internal.Finite n)
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int16 GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int32 GHC.Word.Word32
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int64 GHC.Word.Word64
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int8 GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Int GHC.Int.Int64
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Int GHC.Types.Word
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Word GHC.Word.Word64
- Data.Connection.Class: instance Data.Universe.Class.Finite a => Data.Connection.Class.Connection k () (Data.Functor.Contravariant.Predicate a)
- Data.Connection.Class: instance Data.Universe.Class.Finite a => Data.Connection.Class.Connection k (Data.Functor.Contravariant.Predicate a, Data.Functor.Contravariant.Predicate a) (Data.Functor.Contravariant.Predicate a)
- Data.Connection.Class: instance GHC.TypeNats.KnownNat n => Data.Connection.Class.Connection k () (Data.Finite.Internal.Finite n)
- Data.Connection.Class: maybeL :: Triple () b => Trip (Maybe a) (Either a b)
- Data.Connection.Class: maybeR :: Triple () a => Trip (Maybe b) (Either a b)
- Data.Connection.Class: swapL :: ConnR a b -> ConnL b a
- Data.Connection.Class: swapR :: ConnL a b -> ConnR b a
- Data.Connection.Class: type ConnDouble k = Connection k Double
- Data.Connection.Class: type ConnFloat k = Connection k Float
- Data.Connection.Class: type Extremal k = Connection k ()
- Data.Connection.Class: type Semilattice k a = Connection k (a, a) a
- Data.Connection.Class: type Trip a b = forall k. Conn k a b
- Data.Connection.Conn: counitL :: ConnL a b -> b -> b
- Data.Connection.Conn: counitR :: ConnR a b -> a -> a
- Data.Connection.Conn: fmapped :: Functor f => Conn k a b -> Conn k (f a) (f b)
- Data.Connection.Conn: lowerL :: ConnL a b -> a -> b
- Data.Connection.Conn: lowerL1 :: ConnL a b -> (a -> a) -> b -> b
- Data.Connection.Conn: lowerL2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b
- Data.Connection.Conn: lowerR1 :: ConnR a b -> (b -> b) -> a -> a
- Data.Connection.Conn: lowerR2 :: ConnR a b -> (b -> b -> b) -> a -> a -> a
- Data.Connection.Conn: trip :: (a -> b) -> (b -> a) -> (a -> b) -> Trip a b
- Data.Connection.Conn: type Trip a b = forall k. Conn k a b
- Data.Connection.Conn: unitL :: ConnL a b -> a -> a
- Data.Connection.Conn: unitR :: ConnR a b -> b -> b
- Data.Connection.Conn: upperL1 :: ConnL a b -> (b -> b) -> a -> a
- Data.Connection.Conn: upperL2 :: ConnL a b -> (b -> b -> b) -> a -> a -> a
- Data.Connection.Conn: upperR :: ConnR a b -> a -> b
- Data.Connection.Conn: upperR1 :: ConnR a b -> (a -> a) -> b -> b
- Data.Connection.Conn: upperR2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b
- Data.Connection.Double: covers :: Double -> Double -> Bool
- Data.Connection.Double: epsilon :: Double
- Data.Connection.Double: f64f32 :: Conn k Double Float
- Data.Connection.Double: f64i08 :: Conn k Double (Extended Int8)
- Data.Connection.Double: f64i16 :: Conn k Double (Extended Int16)
- Data.Connection.Double: f64i32 :: Conn k Double (Extended Int32)
- Data.Connection.Double: max64 :: Double -> Double -> Double
- Data.Connection.Double: min64 :: Double -> Double -> Double
- Data.Connection.Double: shift :: Int64 -> Double -> Double
- Data.Connection.Double: ulp :: Double -> Double -> Maybe (Ordering, Word64)
- Data.Connection.Double: until :: (a -> Bool) -> (a -> a -> Bool) -> (a -> a) -> a -> a
- Data.Connection.Double: within :: Word64 -> Double -> Double -> Bool
- Data.Connection.Float: covers :: Float -> Float -> Bool
- Data.Connection.Float: epsilon :: Float
- Data.Connection.Float: shift :: Int32 -> Float -> Float
- Data.Connection.Float: ulp :: Float -> Float -> Maybe (Ordering, Word32)
- Data.Connection.Float: within :: Word32 -> Float -> Float -> Bool
- Data.Connection.Int: i08c08 :: ConnL Int8 CChar
- Data.Connection.Int: i08w08 :: Conn k Int8 Word8
- Data.Connection.Int: i16c16 :: ConnL Int16 CShort
- Data.Connection.Int: i16w16 :: Conn k Int16 Word16
- Data.Connection.Int: i32c32 :: ConnL Int32 CInt
- Data.Connection.Int: i32w32 :: Conn k Int32 Word32
- Data.Connection.Int: i64c64 :: ConnL Int64 CLong
- Data.Connection.Int: i64w64 :: Conn k Int64 Word64
- Data.Connection.Int: intnat :: ConnL Integer Natural
- Data.Connection.Int: ixxi64 :: Conn k Int Int64
- Data.Connection.Int: ixxwxx :: Conn k Int Word
- Data.Connection.Property: ordering :: Trip () Ordering
- Data.Connection.Property: range' :: Triple () a => (a, a)
- Data.Connection.Word: binc08 :: ConnL Bool CBool
- Data.Connection.Word: c08bin :: ConnL CBool Bool
- Data.Connection.Word: w08c08 :: ConnL Word8 CUChar
- Data.Connection.Word: w08i08 :: ConnL Word8 Int8
- Data.Connection.Word: w16c16 :: ConnL Word16 CUShort
- Data.Connection.Word: w16i16 :: ConnL Word16 Int16
- Data.Connection.Word: w32c32 :: ConnL Word32 CUInt
- Data.Connection.Word: w32i32 :: ConnL Word32 Int32
- Data.Connection.Word: w64c64 :: ConnL Word64 CULong
- Data.Connection.Word: w64i64 :: ConnL Word64 Int64
- Data.Connection.Word: wxxw64 :: Conn k Word Word64
- Data.Lattice: class Lattice a => Heyting k a
- Data.Lattice: false :: Lattice a => a
- Data.Lattice: glb :: Triple (a, a) a => a -> a -> a -> a
- Data.Lattice: heytingL :: Lattice a => (a -> a -> a) -> a -> Conn 'L a a
- Data.Lattice: heytingR :: Lattice a => (a -> a -> a) -> a -> Conn 'R a a
- Data.Lattice: instance (Data.Lattice.Heyting k a, Data.Lattice.Heyting k b) => Data.Lattice.Heyting k (a, b)
- Data.Lattice: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Lattice.Boolean (Data.Set.Internal.Set a)
- Data.Lattice: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Set.Internal.Set a)
- Data.Lattice: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Set.Internal.Set a)
- Data.Lattice: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Lattice.Symmetric (Data.Set.Internal.Set a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting a) => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Semigroup.Internal.Endo a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting a) => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Semigroup.Internal.Endo a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting b) => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Functor.Contravariant.Op b a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting b) => Data.Lattice.Heyting 'Data.Connection.Conn.L (a -> b)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting b) => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Functor.Contravariant.Op b a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting b) => Data.Lattice.Heyting 'Data.Connection.Conn.R (a -> b)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Boolean a) => Data.Lattice.Boolean (Data.Semigroup.Internal.Endo a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Boolean b) => Data.Lattice.Boolean (Data.Functor.Contravariant.Op b a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Boolean b) => Data.Lattice.Boolean (a -> b)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Symmetric a) => Data.Lattice.Symmetric (Data.Semigroup.Internal.Endo a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Symmetric b) => Data.Lattice.Symmetric (Data.Functor.Contravariant.Op b a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Symmetric b) => Data.Lattice.Symmetric (a -> b)
- Data.Lattice: instance Data.Lattice.Boolean Data.IntSet.Internal.IntSet
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L ()
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L Data.IntSet.Internal.IntSet
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Int.Int16
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Int.Int32
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Int.Int64
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Int.Int8
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Types.Bool
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Types.Int
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Types.Ordering
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Types.Word
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Word.Word16
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Word.Word32
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Word.Word64
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Word.Word8
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R ()
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R Data.IntSet.Internal.IntSet
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Int.Int16
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Int.Int32
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Int.Int64
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Int.Int8
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Types.Bool
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Types.Int
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Types.Ordering
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Types.Word
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Word.Word16
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Word.Word32
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Word.Word64
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Word.Word8
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R a => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Order.Extended.Extended a)
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R a => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Order.Extended.Lifted a)
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R a => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Order.Extended.Lowered a)
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R a => Data.Lattice.Heyting 'Data.Connection.Conn.R (GHC.Maybe.Maybe a)
- Data.Lattice: instance Data.Lattice.Symmetric Data.IntSet.Internal.IntSet
- Data.Lattice: instance Data.Universe.Class.Finite a => Data.Lattice.Boolean (Data.Functor.Contravariant.Predicate a)
- Data.Lattice: instance Data.Universe.Class.Finite a => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Functor.Contravariant.Predicate a)
- Data.Lattice: instance Data.Universe.Class.Finite a => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Functor.Contravariant.Predicate a)
- Data.Lattice: instance Data.Universe.Class.Finite a => Data.Lattice.Symmetric (Data.Functor.Contravariant.Predicate a)
- Data.Lattice: instance GHC.TypeNats.KnownNat n => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Finite.Internal.Finite n)
- Data.Lattice: instance GHC.TypeNats.KnownNat n => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Finite.Internal.Finite n)
- Data.Lattice: lub :: Triple (a, a) a => a -> a -> a -> a
- Data.Lattice: true :: Lattice a => a
- Data.Lattice: type HeytingL = Heyting 'L
- Data.Lattice: type HeytingR = Heyting 'R
- Data.Lattice: type Semilattice k a = Connection k (a, a) a
- Data.Lattice.Property: heytingL0 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL1 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL10 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL11 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL12 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL13 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL14 :: Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL15 :: Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL16 :: Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL17 :: Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL18 :: Heyting 'L c => c -> Bool
- Data.Lattice.Property: heytingL19 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL2 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL20 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL3 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL4 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL5 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL6 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL7 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL8 :: forall a. Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL9 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingR0 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR1 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR10 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR11 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR12 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR13 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR14 :: Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR15 :: Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR16 :: Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR17 :: Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR2 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR3 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR4 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR5 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR6 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR7 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR8 :: forall a. Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR9 :: Heyting 'R a => a -> a -> Bool
- Data.Order: (<) :: Preorder a => a -> a -> Bool
- Data.Order: (>) :: Preorder a => a -> a -> Bool
- Data.Order: instance (Data.Order.Total a, Data.Order.Preorder r, Data.Universe.Class.Finite r) => Data.Order.Preorder (Control.Monad.Trans.Cont.Cont r a)
- Data.Order: instance (Data.Order.Total a, Data.Order.Preorder r, Data.Universe.Class.Finite r) => Data.Order.Preorder (Control.Monad.Trans.Select.Select r a)
- Data.Order: instance (Data.Universe.Class.Finite a, Data.Order.Preorder a) => Data.Order.Preorder (Data.Semigroup.Internal.Endo a)
- Data.Order: instance (Data.Universe.Class.Finite a, Data.Order.Preorder b) => Data.Order.Preorder (Data.Functor.Contravariant.Op b a)
- Data.Order: instance (Data.Universe.Class.Finite a, Data.Order.Preorder b) => Data.Order.Preorder (a -> b)
- Data.Order: instance (Data.Universe.Class.Finite a, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Semigroup.Internal.Endo a)
- Data.Order: instance (Data.Universe.Class.Finite a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Functor.Contravariant.Op b a)
- Data.Order: instance (Data.Universe.Class.Finite a, GHC.Classes.Eq b) => GHC.Classes.Eq (a -> b)
- Data.Order: instance Data.Order.Preorder (Data.Finite.Internal.Finite n)
- Data.Order: instance Data.Universe.Class.Finite a => Data.Order.Preorder (Data.Functor.Contravariant.Predicate a)
- Data.Order: instance Data.Universe.Class.Finite a => GHC.Classes.Eq (Data.Functor.Contravariant.Predicate a)
- Data.Order.Interval: open32 :: Float -> Float -> Interval Float
- Data.Order.Interval: open32L :: Float -> Float -> Interval Float
- Data.Order.Interval: open32R :: Float -> Float -> Interval Float
- Data.Order.Interval: open64 :: Double -> Double -> Interval Double
- Data.Order.Interval: open64L :: Double -> Double -> Interval Double
- Data.Order.Interval: open64R :: Double -> Double -> Interval Double
+ Data.Connection.Class: (/|\) :: Connection k (c, c) c => Conn k a c -> Conn k b c -> Conn k (a, b) c
+ Data.Connection.Class: (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ Data.Connection.Class: (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ Data.Connection.Class: (\|/) :: Conn k c a -> Conn k c b -> Conn k c (Either a b)
+ Data.Connection.Class: embed :: Conn k a b -> b -> a
+ Data.Connection.Class: extremal :: Triple () a => Conn k a Bool
+ Data.Connection.Class: half :: (Num a, Preorder a) => ConnK a b -> a -> Maybe Ordering
+ Data.Connection.Class: identity :: Conn k a a
+ Data.Connection.Class: infixr 1 <<<
+ Data.Connection.Class: infixr 3 \|/
+ Data.Connection.Class: infixr 4 /|\
+ Data.Connection.Class: instance (Data.Connection.Class.Left () a, Data.Order.Preorder b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L () (Data.Either.Either a b)
+ Data.Connection.Class: instance (Data.Connection.Class.Triple () a, Data.Order.Preorder b) => Data.Connection.Class.Connection k (GHC.Maybe.Maybe b) (Data.Either.Either a b)
+ Data.Connection.Class: instance (Data.Order.Preorder a, Data.Connection.Class.Right () b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.Either.Either a b)
+ Data.Connection.Class: instance (Data.Order.Preorder a, Data.Connection.Class.Triple () b) => Data.Connection.Class.Connection k (GHC.Maybe.Maybe a) (Data.Either.Either a b)
+ Data.Connection.Class: instance (Data.Order.Total a, Data.Connection.Class.Left (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.Map.Internal.Map a b, Data.Map.Internal.Map a b) (Data.Map.Internal.Map a b)
+ Data.Connection.Class: instance (Data.Order.Total a, Data.Connection.Class.Right (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.Map.Internal.Map a b, Data.Map.Internal.Map a b) (Data.Map.Internal.Map a b)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L () Data.IntSet.Internal.IntSet
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L () GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 (GHC.Maybe.Maybe GHC.Int.Int32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Word.Word16
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int64 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int64 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int64 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int64 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Int.Int16)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Int.Int32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Word.Word16
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Word.Word8
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Integer.Type.Integer GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Natural.Natural (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Int (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Int GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Int GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Int GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Word (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Word GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 (GHC.Maybe.Maybe GHC.Int.Int32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word64 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word64 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Int.Int16)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Int.Int32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Word.Word16
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Order.Positive GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int16 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int32 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int64 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int64 GHC.Types.Int
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int8 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Real.Rational GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Double GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Float GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Int GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Ordering GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Word GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word16 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word32 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word64 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word64 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word8 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Left (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.IntMap.Internal.IntMap a, Data.IntMap.Internal.IntMap a) (Data.IntMap.Internal.IntMap a)
+ Data.Connection.Class: instance Data.Connection.Class.Right () a => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (GHC.Maybe.Maybe a)
+ Data.Connection.Class: instance Data.Connection.Class.Right (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.IntMap.Internal.IntMap a, Data.IntMap.Internal.IntMap a) (Data.IntMap.Internal.IntMap a)
+ Data.Connection.Class: join :: Left (a, a) a => a -> a -> a
+ Data.Connection.Class: meet :: Right (a, a) a => a -> a -> a
+ Data.Connection.Class: midpoint :: Fractional a => ConnK a b -> a -> a
+ Data.Connection.Class: range :: Conn k a b -> a -> (b, b)
+ Data.Connection.Class: round :: forall a b. (Num a, Triple a b) => a -> b
+ Data.Connection.Class: round1 :: (Num a, Triple a b) => (a -> a) -> b -> b
+ Data.Connection.Class: round2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b
+ Data.Connection.Class: truncate :: (Num a, Triple a b) => a -> b
+ Data.Connection.Class: truncate1 :: (Num a, Triple a b) => (a -> a) -> b -> b
+ Data.Connection.Class: truncate2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b
+ Data.Connection.Class: type ConnK a b = forall k. Conn k a b
+ Data.Connection.Class: type Left = Connection 'L
+ Data.Connection.Class: type Right = Connection 'R
+ Data.Connection.Conn: (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ Data.Connection.Conn: (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ Data.Connection.Conn: ceilingWith :: ConnL a b -> a -> b
+ Data.Connection.Conn: ceilingWith1 :: ConnL a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: ceilingWith2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: counit :: ConnL a b -> b -> b
+ Data.Connection.Conn: filterWith :: Preorder b => ConnL a b -> a -> b -> Bool
+ Data.Connection.Conn: floorWith :: ConnR a b -> a -> b
+ Data.Connection.Conn: floorWith1 :: ConnR a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: floorWith2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: half :: (Num a, Preorder a) => ConnK a b -> a -> Maybe Ordering
+ Data.Connection.Conn: idealWith :: Preorder b => ConnR a b -> a -> b -> Bool
+ Data.Connection.Conn: identity :: Conn k a a
+ Data.Connection.Conn: infixr 1 <<<
+ Data.Connection.Conn: lower :: ConnR a b -> a -> a
+ Data.Connection.Conn: lower1 :: ConnR a b -> (b -> b) -> a -> a
+ Data.Connection.Conn: lower2 :: ConnR a b -> (b -> b -> b) -> a -> a -> a
+ Data.Connection.Conn: midpoint :: Fractional a => ConnK a b -> a -> a
+ Data.Connection.Conn: roundWith :: forall a b. (Num a, Preorder a) => ConnK a b -> a -> b
+ Data.Connection.Conn: roundWith1 :: (Num a, Preorder a) => ConnK a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: roundWith2 :: (Num a, Preorder a) => ConnK a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: truncateWith :: (Num a, Preorder a) => ConnK a b -> a -> b
+ Data.Connection.Conn: truncateWith1 :: (Num a, Preorder a) => ConnK a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: truncateWith2 :: (Num a, Preorder a) => ConnK a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: type ConnK a b = forall k. Conn k a b
+ Data.Connection.Conn: unit :: ConnR a b -> b -> b
+ Data.Connection.Conn: upL :: ConnL (Down a) (Down b) -> ConnL b a
+ Data.Connection.Conn: upR :: ConnR (Down a) (Down b) -> ConnR b a
+ Data.Connection.Conn: upper :: ConnL a b -> a -> a
+ Data.Connection.Conn: upper1 :: ConnL a b -> (b -> b) -> a -> a
+ Data.Connection.Conn: upper2 :: ConnL a b -> (b -> b -> b) -> a -> a -> a
+ Data.Connection.Float: f64f32 :: Conn k Double Float
+ Data.Connection.Float: f64i08 :: Conn k Double (Extended Int8)
+ Data.Connection.Float: f64i16 :: Conn k Double (Extended Int16)
+ Data.Connection.Float: f64i32 :: Conn k Double (Extended Int32)
+ Data.Connection.Float: max64 :: Double -> Double -> Double
+ Data.Connection.Float: min64 :: Double -> Double -> Double
+ Data.Connection.Float: near32 :: Word32 -> Float -> Float -> Bool
+ Data.Connection.Float: near64 :: Word64 -> Double -> Double -> Bool
+ Data.Connection.Float: shift32 :: Int32 -> Float -> Float
+ Data.Connection.Float: shift64 :: Int64 -> Double -> Double
+ Data.Connection.Float: ulp32 :: Float -> Float -> Maybe (Ordering, Word32)
+ Data.Connection.Float: ulp64 :: Double -> Double -> Maybe (Ordering, Word64)
+ Data.Connection.Float: until :: (a -> Bool) -> (a -> a -> Bool) -> (a -> a) -> a -> a
+ Data.Connection.Int: i08ixx :: ConnL Int8 (Maybe Int)
+ Data.Connection.Int: i16ixx :: ConnL Int16 (Maybe Int)
+ Data.Connection.Int: i32ixx :: ConnL Int32 (Maybe Int)
+ Data.Connection.Int: i64ixx :: Conn k Int64 Int
+ Data.Connection.Int: w08i16 :: ConnL Word8 (Maybe Int16)
+ Data.Connection.Int: w08i32 :: ConnL Word8 (Maybe Int32)
+ Data.Connection.Int: w08i64 :: ConnL Word8 (Maybe Int64)
+ Data.Connection.Int: w08int :: ConnL Word8 (Maybe Integer)
+ Data.Connection.Int: w08ixx :: ConnL Word8 (Maybe Int)
+ Data.Connection.Int: w16i32 :: ConnL Word16 (Maybe Int32)
+ Data.Connection.Int: w16i64 :: ConnL Word16 (Maybe Int64)
+ Data.Connection.Int: w16int :: ConnL Word16 (Maybe Integer)
+ Data.Connection.Int: w16ixx :: ConnL Word16 (Maybe Int)
+ Data.Connection.Int: w32i64 :: ConnL Word32 (Maybe Int64)
+ Data.Connection.Int: w32int :: ConnL Word32 (Maybe Integer)
+ Data.Connection.Int: w32ixx :: ConnL Word32 (Maybe Int)
+ Data.Connection.Int: w64int :: ConnL Word64 (Maybe Integer)
+ Data.Connection.Int: wxxint :: ConnL Word (Maybe Integer)
+ Data.Connection.Word: i08nat :: ConnL Int8 Natural
+ Data.Connection.Word: i08w08 :: ConnL Int8 Word8
+ Data.Connection.Word: i08w16 :: ConnL Int8 Word16
+ Data.Connection.Word: i08w32 :: ConnL Int8 Word32
+ Data.Connection.Word: i08w64 :: ConnL Int8 Word64
+ Data.Connection.Word: i08wxx :: ConnL Int8 Word
+ Data.Connection.Word: i16nat :: ConnL Int16 Natural
+ Data.Connection.Word: i16w16 :: ConnL Int16 Word16
+ Data.Connection.Word: i16w32 :: ConnL Int16 Word32
+ Data.Connection.Word: i16w64 :: ConnL Int16 Word64
+ Data.Connection.Word: i16wxx :: ConnL Int16 Word
+ Data.Connection.Word: i32nat :: ConnL Int32 Natural
+ Data.Connection.Word: i32w32 :: ConnL Int32 Word32
+ Data.Connection.Word: i32w64 :: ConnL Int32 Word64
+ Data.Connection.Word: i32wxx :: ConnL Int32 Word
+ Data.Connection.Word: i64nat :: ConnL Int64 Natural
+ Data.Connection.Word: i64w64 :: ConnL Int64 Word64
+ Data.Connection.Word: i64wxx :: ConnL Int64 Word
+ Data.Connection.Word: intnat :: ConnL Integer Natural
+ Data.Connection.Word: ixxnat :: ConnL Int Natural
+ Data.Connection.Word: ixxw64 :: ConnL Int Word64
+ Data.Connection.Word: ixxwxx :: ConnL Int Word
+ Data.Connection.Word: w64wxx :: Conn k Word64 Word
+ Data.Lattice: algebra :: Algebra k a => a -> Conn k a a
+ Data.Lattice: bottom :: Join a => a
+ Data.Lattice: bounded :: (Semilattice k a, Connection k () a) => Conn k () a
+ Data.Lattice: class Semilattice k a => Algebra k a
+ Data.Lattice: class Order a => Semilattice (k :: Kan) a
+ Data.Lattice: coheyting :: Join a => (a -> a -> a) -> a -> ConnL a a
+ Data.Lattice: instance (Data.Lattice.Coheyting a, Data.Lattice.Coheyting b) => Data.Lattice.Algebra 'Data.Connection.Conn.L (a, b)
+ Data.Lattice: instance (Data.Lattice.Heyting a, Data.Lattice.Heyting b) => Data.Lattice.Algebra 'Data.Connection.Conn.R (a, b)
+ Data.Lattice: instance (Data.Lattice.Join a, Data.Lattice.Join b) => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.Either.Either a b)
+ Data.Lattice: instance (Data.Lattice.Lattice a, Data.Lattice.Lattice b) => Data.Lattice.Semilattice k (a, b)
+ Data.Lattice: instance (Data.Lattice.Meet a, Data.Lattice.Meet b) => Data.Lattice.Semilattice 'Data.Connection.Conn.R (Data.Either.Either a b)
+ Data.Lattice: instance (Data.Order.Total k, Data.Lattice.Join a) => Data.Lattice.Algebra 'Data.Connection.Conn.L (Data.Map.Internal.Map k a)
+ Data.Lattice: instance (Data.Order.Total k, Data.Lattice.Join a) => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.Map.Internal.Map k a)
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L ()
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L Data.IntSet.Internal.IntSet
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Int.Int16
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Int.Int32
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Int.Int64
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Int.Int8
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Types.Bool
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Types.Int
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Types.Ordering
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Types.Word
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Word.Word16
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Word.Word32
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Word.Word64
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Word.Word8
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R ()
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Int.Int16
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Int.Int32
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Int.Int64
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Int.Int8
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Types.Bool
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Types.Int
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Types.Ordering
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Types.Word
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Word.Word16
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Word.Word32
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Word.Word64
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Word.Word8
+ Data.Lattice: instance Data.Lattice.Boolean GHC.Types.Ordering
+ Data.Lattice: instance Data.Lattice.Heyting a => Data.Lattice.Algebra 'Data.Connection.Conn.R (Data.Order.Extended.Extended a)
+ Data.Lattice: instance Data.Lattice.Heyting a => Data.Lattice.Algebra 'Data.Connection.Conn.R (Data.Order.Extended.Lifted a)
+ Data.Lattice: instance Data.Lattice.Heyting a => Data.Lattice.Algebra 'Data.Connection.Conn.R (Data.Order.Extended.Lowered a)
+ Data.Lattice: instance Data.Lattice.Heyting a => Data.Lattice.Algebra 'Data.Connection.Conn.R (GHC.Maybe.Maybe a)
+ Data.Lattice: instance Data.Lattice.Join a => Data.Lattice.Algebra 'Data.Connection.Conn.L (Data.IntMap.Internal.IntMap a)
+ Data.Lattice: instance Data.Lattice.Join a => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.IntMap.Internal.IntMap a)
+ Data.Lattice: instance Data.Lattice.Join a => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.Order.Extended.Extended a)
+ Data.Lattice: instance Data.Lattice.Join a => Data.Lattice.Semilattice 'Data.Connection.Conn.L (GHC.Maybe.Maybe a)
+ Data.Lattice: instance Data.Lattice.Meet a => Data.Lattice.Semilattice 'Data.Connection.Conn.R (Data.Order.Extended.Extended a)
+ Data.Lattice: instance Data.Lattice.Meet a => Data.Lattice.Semilattice 'Data.Connection.Conn.R (GHC.Maybe.Maybe a)
+ Data.Lattice: instance Data.Lattice.Semilattice 'Data.Connection.Conn.L Data.IntSet.Internal.IntSet
+ Data.Lattice: instance Data.Lattice.Semilattice k ()
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Int.Int16
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Int.Int32
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Int.Int64
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Int.Int8
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Types.Bool
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Types.Int
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Types.Ordering
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Types.Word
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Word.Word16
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Word.Word32
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Word.Word64
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Word.Word8
+ Data.Lattice: instance Data.Order.Total a => Data.Lattice.Algebra 'Data.Connection.Conn.L (Data.Set.Internal.Set a)
+ Data.Lattice: instance Data.Order.Total a => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.Set.Internal.Set a)
+ Data.Lattice: semilattice :: (Semilattice k a, Connection k (a, a) a) => Conn k (a, a) a
+ Data.Lattice: top :: Meet a => a
+ Data.Lattice: type Coheyting a = (Lattice a, Algebra 'L a)
+ Data.Lattice: type Heyting a = (Lattice a, Algebra 'R a)
+ Data.Lattice: type Join = Semilattice 'L
+ Data.Lattice: type Meet = Semilattice 'R
+ Data.Lattice.Property: coheyting0 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting1 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting10 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting11 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting12 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting13 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting14 :: Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting15 :: Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting16 :: Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting17 :: Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting18 :: Coheyting c => c -> Bool
+ Data.Lattice.Property: coheyting19 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting2 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting20 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting3 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting4 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting5 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting6 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting7 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting8 :: forall a. Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting9 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting0 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting1 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting10 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting11 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting12 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting13 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting14 :: Heyting a => a -> Bool
+ Data.Lattice.Property: heyting15 :: Heyting a => a -> Bool
+ Data.Lattice.Property: heyting16 :: Heyting a => a -> Bool
+ Data.Lattice.Property: heyting17 :: Heyting a => a -> Bool
+ Data.Lattice.Property: heyting2 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting3 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting4 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting5 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting6 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting7 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting8 :: forall a. Heyting a => a -> Bool
+ Data.Lattice.Property: heyting9 :: Heyting a => a -> a -> Bool
+ Data.Order: [getDown] :: Down a -> a
+ Data.Order: pgt :: Preorder a => a -> a -> Bool
+ Data.Order: plt :: Preorder a => a -> a -> Bool
+ Data.Order.Syntax: (<) :: Preorder a => a -> a -> Bool
+ Data.Order.Syntax: (>) :: Preorder a => a -> a -> Bool
- Data.Connection.Class: ceiling :: Connection 'L a b => a -> b
+ Data.Connection.Class: ceiling :: Left a b => a -> b
- Data.Connection.Class: ceiling1 :: Connection 'L a b => (a -> a) -> b -> b
+ Data.Connection.Class: ceiling1 :: Left a b => (a -> a) -> b -> b
- Data.Connection.Class: ceiling2 :: Connection 'L a b => (a -> a -> a) -> b -> b -> b
+ Data.Connection.Class: ceiling2 :: Left a b => (a -> a -> a) -> b -> b -> b
- Data.Connection.Class: connL :: Connection 'L a b => ConnL a b
+ Data.Connection.Class: connL :: Left a b => ConnL a b
- Data.Connection.Class: connR :: Connection 'R a b => ConnR a b
+ Data.Connection.Class: connR :: Right a b => ConnR a b
- Data.Connection.Class: embedL :: Connection 'L a b => b -> a
+ Data.Connection.Class: embedL :: Left a b => b -> a
- Data.Connection.Class: embedR :: Connection 'R a b => b -> a
+ Data.Connection.Class: embedR :: Right a b => b -> a
- Data.Connection.Class: floor :: Connection 'R a b => a -> b
+ Data.Connection.Class: floor :: Right a b => a -> b
- Data.Connection.Class: floor1 :: Connection 'R a b => (a -> a) -> b -> b
+ Data.Connection.Class: floor1 :: Right a b => (a -> a) -> b -> b
- Data.Connection.Class: floor2 :: Connection 'R a b => (a -> a -> a) -> b -> b -> b
+ Data.Connection.Class: floor2 :: Right a b => (a -> a -> a) -> b -> b -> b
- Data.Connection.Class: infixr 5 \/
+ Data.Connection.Class: infixr 5 `join`
- Data.Connection.Class: infixr 6 /\
+ Data.Connection.Class: infixr 6 `meet`
- Data.Connection.Class: maximal :: Extremal 'R a => a
+ Data.Connection.Class: maximal :: Right () a => a
- Data.Connection.Class: minimal :: Extremal 'L a => a
+ Data.Connection.Class: minimal :: Left () a => a
- Data.Connection.Class: type ConnExtended k a b = Connection k a (Extended b)
+ Data.Connection.Class: type ConnExtended a b = Triple a (Extended b)
- Data.Connection.Class: type ConnInteger k = Connection k (Maybe Integer)
+ Data.Connection.Class: type ConnInteger a = Left a (Maybe Integer)
- Data.Connection.Class: type ConnL = Conn 'L
+ Data.Connection.Class: type ConnL = Conn 'L
- Data.Connection.Class: type ConnR = Conn 'R
+ Data.Connection.Class: type ConnR = Conn 'R
- Data.Connection.Class: type ConnRational k = Connection k Rational
+ Data.Connection.Class: type ConnRational a = Triple Rational a
- Data.Connection.Class: type Triple a b = (Connection 'L a b, Connection 'R a b)
+ Data.Connection.Class: type Triple a b = (Left a b, Right a b)
- Data.Connection.Conn: range :: Trip a b -> a -> (b, b)
+ Data.Connection.Conn: range :: Conn k a b -> a -> (b, b)
- Data.Connection.Conn: type ConnL = Conn 'L
+ Data.Connection.Conn: type ConnL = Conn 'L
- Data.Connection.Conn: type ConnR = Conn 'R
+ Data.Connection.Conn: type ConnR = Conn 'R
- Data.Connection.Int: i08i16 :: ConnL Int8 Int16
+ Data.Connection.Int: i08i16 :: ConnL Int8 (Maybe Int16)
- Data.Connection.Int: i08i32 :: ConnL Int8 Int32
+ Data.Connection.Int: i08i32 :: ConnL Int8 (Maybe Int32)
- Data.Connection.Int: i08i64 :: ConnL Int8 Int64
+ Data.Connection.Int: i08i64 :: ConnL Int8 (Maybe Int64)
- Data.Connection.Int: i16i32 :: ConnL Int16 Int32
+ Data.Connection.Int: i16i32 :: ConnL Int16 (Maybe Int32)
- Data.Connection.Int: i16i64 :: ConnL Int16 Int64
+ Data.Connection.Int: i16i64 :: ConnL Int16 (Maybe Int64)
- Data.Connection.Int: i32i64 :: ConnL Int32 Int64
+ Data.Connection.Int: i32i64 :: ConnL Int32 (Maybe Int64)
- Data.Connection.Property: adjoint :: (Preorder a, Preorder b) => Trip a b -> a -> b -> Bool
+ Data.Connection.Property: adjoint :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool
- Data.Connection.Property: closed :: (Preorder a, Preorder b) => Trip a b -> a -> Bool
+ Data.Connection.Property: closed :: (Preorder a, Preorder b) => ConnK a b -> a -> Bool
- Data.Connection.Property: idempotent :: (Preorder a, Preorder b) => Trip a b -> a -> b -> Bool
+ Data.Connection.Property: idempotent :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool
- Data.Connection.Property: kernel :: (Preorder a, Preorder b) => Trip a b -> b -> Bool
+ Data.Connection.Property: kernel :: (Preorder a, Preorder b) => ConnK a b -> b -> Bool
- Data.Connection.Property: monotonic :: (Preorder a, Preorder b) => Trip a b -> a -> a -> b -> b -> Bool
+ Data.Connection.Property: monotonic :: (Preorder a, Preorder b) => ConnK a b -> a -> a -> b -> b -> Bool
- Data.Lattice: (//) :: Heyting 'R a => a -> a -> a
+ Data.Lattice: (//) :: Algebra 'R a => a -> a -> a
- Data.Lattice: (/\) :: Semilattice 'R a => a -> a -> a
+ Data.Lattice: (/\) :: Meet a => a -> a -> a
- Data.Lattice: (\/) :: Semilattice 'L a => a -> a -> a
+ Data.Lattice: (\/) :: Join a => a -> a -> a
- Data.Lattice: (\\) :: Heyting 'L a => a -> a -> a
+ Data.Lattice: (\\) :: Algebra 'L a => a -> a -> a
- Data.Lattice: boolean :: Boolean a => Trip a a
+ Data.Lattice: boolean :: Boolean a => Conn k a a
- Data.Lattice: booleanL :: Heyting 'L a => Conn 'L a a
+ Data.Lattice: booleanL :: Coheyting a => ConnL a a
- Data.Lattice: booleanR :: Heyting 'R a => Conn 'R a a
+ Data.Lattice: booleanR :: Heyting a => ConnR a a
- Data.Lattice: boundary :: Heyting 'L a => a -> a
+ Data.Lattice: boundary :: Coheyting a => a -> a
- Data.Lattice: equiv :: Heyting 'L a => a -> a -> a
+ Data.Lattice: equiv :: Algebra 'L a => a -> a -> a
- Data.Lattice: heyting :: Heyting k a => a -> Conn k a a
+ Data.Lattice: heyting :: Meet a => (a -> a -> a) -> a -> ConnR a a
- Data.Lattice: iff :: Heyting 'R a => a -> a -> a
+ Data.Lattice: iff :: Algebra 'R a => a -> a -> a
- Data.Lattice: middle :: Heyting 'R a => a -> a
+ Data.Lattice: middle :: Heyting a => a -> a
- Data.Lattice: neg :: Heyting 'R a => a -> a
+ Data.Lattice: neg :: Heyting a => a -> a
- Data.Lattice: non :: Heyting 'L a => a -> a
+ Data.Lattice: non :: Coheyting a => a -> a
- Data.Lattice: type Biheyting a = (HeytingL a, HeytingR a)
+ Data.Lattice: type Biheyting a = (Coheyting a, Heyting a)
- Data.Lattice: type Lattice a = (Eq a, Semilattice 'L a, Extremal 'L a, Semilattice 'R a, Extremal 'R a)
+ Data.Lattice: type Lattice a = (Join a, Meet a)
- Data.Lattice.Property: boolean0 :: (Heyting R a, Heyting L a) => a -> Bool
+ Data.Lattice.Property: boolean0 :: Biheyting a => a -> Bool
- Data.Lattice.Property: boolean1 :: Heyting R a => a -> Bool
+ Data.Lattice.Property: boolean1 :: Heyting a => a -> Bool
- Data.Lattice.Property: boolean2 :: Heyting R a => a -> Bool
+ Data.Lattice.Property: boolean2 :: Heyting a => a -> Bool
- Data.Lattice.Property: boolean3 :: Heyting L a => a -> Bool
+ Data.Lattice.Property: boolean3 :: Coheyting a => a -> Bool
- Data.Lattice.Property: boolean4 :: Heyting R a => a -> a -> Bool
+ Data.Lattice.Property: boolean4 :: Heyting a => a -> a -> Bool
- Data.Lattice.Property: boolean5 :: (Heyting L a, Heyting R a) => a -> a -> Bool
+ Data.Lattice.Property: boolean5 :: Biheyting a => a -> a -> Bool
- Data.Lattice.Property: boolean6 :: (Heyting R a, Heyting L a) => a -> a -> Bool
+ Data.Lattice.Property: boolean6 :: Biheyting a => a -> a -> Bool
- Data.Lattice.Property: symmetric1 :: (Heyting R a, Heyting L a) => a -> Bool
+ Data.Lattice.Property: symmetric1 :: Biheyting a => a -> Bool
- Data.Lattice.Property: symmetric12 :: Symmetric c => c -> c -> Bool
+ Data.Lattice.Property: symmetric12 :: Symmetric a => a -> a -> Bool
- Data.Lattice.Property: symmetric13 :: Symmetric c => c -> c -> Bool
+ Data.Lattice.Property: symmetric13 :: Symmetric a => a -> a -> Bool
- Data.Lattice.Property: symmetric2 :: Symmetric c => c -> Bool
+ Data.Lattice.Property: symmetric2 :: Symmetric a => a -> Bool
- Data.Lattice.Property: symmetric3 :: Symmetric c => c -> Bool
+ Data.Lattice.Property: symmetric3 :: Symmetric a => a -> Bool
- Data.Lattice.Property: symmetric4 :: Symmetric c => c -> Bool
+ Data.Lattice.Property: symmetric4 :: Symmetric a => a -> Bool
- Data.Lattice.Property: symmetric5 :: Symmetric c => c -> Bool
+ Data.Lattice.Property: symmetric5 :: Symmetric a => a -> Bool
- Data.Lattice.Property: symmetric6 :: Heyting R a => a -> Bool
+ Data.Lattice.Property: symmetric6 :: Heyting a => a -> Bool

Files

ChangeLog.md view
@@ -2,6 +2,21 @@  ## 0.0.3  -- 2020-02-17 -* `Data.Float` : add cmath utils+* `Data.Connection.Float` : float utils * `Data.Connection.Ratio` : add rational connections-* `Numeric.Prelude` : add numeric prelude++## 0.1.0  -- 2020-07-07++* Unify `Connection` and `Triple` into a single class+* Add `Heyting`, `Symmetric`, and `Boolean` algebras+* Add misc new instances++## 0.2.0  -- 2021-02-21++* Change integral connection instances to non-shifting behavior.+* Move all one-sided `Connection` instances to `Connection 'L`.+* Consolidate floating point utilities into one module.+* Rename some functions in `Class.hs` and `Conn.hs` for clarity.+* Move `<` and `>` to `Syntax.hs`.+* Remove niche instances w/ upstream dependencies.+* Add misc new instances.
connections.cabal view
@@ -1,5 +1,5 @@ name:                connections-version:             0.1.0+version:             0.2.0 synopsis:            Orders, Galois connections, and lattices. description:         A library for order manipulation using Galois connections. homepage:            https://github.com/cmk/connections@@ -26,7 +26,6 @@     , Data.Connection.Word     , Data.Connection.Ratio     , Data.Connection.Float-    , Data.Connection.Double     , Data.Connection.Property      , Data.Lattice@@ -41,19 +40,7 @@   build-depends:              base            >= 4.10  && < 5.0     , containers      >= 0.4.0 && < 1.0-    , transformers    >= 0.5.5 && < 0.6-    , universe-base   >= 1.1.1 && < 2.0-    , finite-typelits >= 0.1.4.2 && < 0.1.5 -  default-extensions:-      ScopedTypeVariables-    , TypeApplications-    , MultiParamTypeClasses-    , UndecidableInstances-    , FlexibleInstances-    , FlexibleContexts-    , TypeOperators- test-suite test   type: exitcode-stdio-1.0   other-modules:@@ -76,3 +63,23 @@   hs-source-dirs: test   default-language: Haskell2010   ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall++executable doctest+  main-is:           doctest.hs+  ghc-options:       -Wall -threaded+  hs-source-dirs:    test+  default-language:  Haskell2010+  x-doctest-options: --fast++  build-depends:+      base+    , doctest                >= 0.8+    , connections -any++  default-extensions: +      ScopedTypeVariables+    , TypeApplications+    , MultiParamTypeClasses+    , UndecidableInstances+    , FlexibleInstances+    , FlexibleContexts
src/Data/Connection.hs view
@@ -1,187 +1,9 @@-{-# Language TypeApplications    #-}-{-# Language AllowAmbiguousTypes #-}-{-# Language ConstraintKinds     #-}-{-# Language DataKinds           #-}-{-# Language Safe                #-}-{-# Language ViewPatterns        #-}-{-# Language PatternSynonyms     #-}-{-# Language RankNTypes          #-}-{-# Language QuantifiedConstraints #-}+{-# LANGUAGE Safe #-}  module Data.Connection (-  -- * Types-    Kan(..)-  , Semilattice-  , Extremal-  , ConnFloat-  , ConnDouble-  , ConnInteger-  , ConnRational-  , ConnExtended-  -- * Connection L-  , type ConnL-  , pattern ConnL-  , connL-  , swapL-  , embedL-  , ceiling-  , ceiling1-  , ceiling2-  , filterL-  , minimal-  , (\/)-  , glb-  -- * Connection R-  , type ConnR-  , pattern ConnR-  , connR-  , swapR-  , floor-  , floor1-  , floor2-  , embedR-  , filterR-  , maximal-  , (/\)-  , lub-  -- * Connection-  , type Trip-  , pattern Conn-  , half-  , midpoint-  , round-  , round1-  , round2-  , truncate-  , truncate1-  , truncate2-  , maybeL-  , maybeR-  , choice-  , strong-  , fmapped-  -- * Connection-  , Conn()-  , Triple-  , Connection(..)+    module Data.Connection.Conn,+    module Data.Connection.Class, ) where -import safe Data.Connection.Conn import safe Data.Connection.Class-import safe Data.Order-import safe Prelude hiding-  (Bounded,fromInteger, fromRational, floor, ceiling, round, truncate)---- $setup--- >>> :set -XTypeApplications--- >>> import Data.Int--- >>> import Prelude hiding (Ord(..), Bounded, fromInteger, fromRational, RealFrac(..))--- >>> import qualified Prelude as P--- >>> :load Data.Connection---- | Determine which half of the interval between 2 representations of /a/ a particular value lies.--- --- @ 'half' t x = 'pcompare' (x - 'counitR' t x) ('unitL' t x - x) @----half :: (Num a, Preorder a) => Trip a b -> a -> Maybe Ordering-half t x = pcompare (x - counitR t x) (unitL t x - x) ---- | Return the midpoint of the interval containing x.------ >>> midpoint f32i08 4.3--- 4.5--- >>> midpoint f64i08 4.3--- 4.5--- >>> pi - midpoint f64f32 pi--- 3.1786509424591713e-8------ >>> maybe False (~~ EQ) $ half f64f32 (midpoint f64f32 pi)--- True----midpoint :: Fractional a => Trip a b -> a -> a-midpoint t x = counitR t x / 2 + unitL t x / 2-------------------------------------------------------------------------- Rounding-------------------------------------------------------------------------- | Return the nearest value to x.------ > round @a @a = id--- --- If x lies halfway between two finite values, then return the value--- with the larger absolute value (i.e. round away from zero).------ See <https://en.wikipedia.org/wiki/Rounding>.------ Usable in conjunction with /RebindableSyntax/:------ >>> fromRational = round--- >>> fromRational @Float 1.3--- 1.3--- >>> fromRational @Float (1 :% 0)--- Infinity--- >>> fromRational @Float (0 :% 0)--- NaN----round :: forall a b. (Num a, Triple a b) => a -> b-round x = case pcompare halfR halfL of-  Just GT -> ceiling x-  Just LT -> floor x-  _       -> truncate x--  where-    halfR = x - counitR (connR @a @b) x -- dist from lower bound--    halfL = unitL (connL @a @b) x - x -- dist from upper bound---- | Lift a unary function over a 'Trip'.------ Results are rounded to the nearest value with ties away from 0.----round1 :: forall a b. (Num a, Triple a b) => (a -> a) -> b -> b-round1 f x = round $ f (g x) where Conn _ g _ = connL-{-# INLINE round1 #-}---- | Lift a binary function over a 'Trip'.------ Results are rounded to the nearest value with ties away from 0.------ >>> f x y = (x + y) - x --- >>> maxOdd32 = 1.6777215e7--- >>> maxOdd64 = 9.007199254740991e15--- >>> f maxOdd32 2.0 :: Float--- 1.0--- >>> round2 @Rational @Float f maxOdd32 2.0--- 2.0--- >>> f maxOdd64 2.0 :: Double--- 1.0--- >>> round2 @Rational @Double f maxOdd64 2.0--- 2.0----round2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b-round2 f x y = round $ f (g x) (g y) where Conn _ g _ = connL-{-# INLINE round2 #-}---- | Truncate towards zero.------ > truncate @a @a = id----truncate :: (Num a, Triple a b) => a -> b-truncate x = if x >~ 0 then floor x else ceiling x---- | Lift a unary function over a 'Trip'.------ Results are truncated towards 0.----truncate1 :: (Num a, Triple a b) => (a -> a) -> b -> b-truncate1 f x = truncate $ f (g x) where Conn _ g _ = connL-{-# INLINE truncate1 #-}---- | Lift a binary function over a 'Trip'.------ Results are truncated towards 0.----truncate2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b-truncate2 f x y = truncate $ f (g x) (g y) where Conn _ g _ = connL-{-# INLINE truncate2 #-}+import safe Data.Connection.Conn
src/Data/Connection/Class.hs view
@@ -1,815 +1,706 @@-{-# Language TypeApplications    #-}-{-# Language AllowAmbiguousTypes #-}-{-# Language ConstraintKinds     #-}-{-# Language DataKinds           #-}-{-# Language Safe                #-}-{-# Language ViewPatterns        #-}-{-# Language PatternSynonyms     #-}-{-# Language RankNTypes          #-}-{-# LANGUAGE DerivingVia         #-}-{-# LANGUAGE StandaloneDeriving  #-}--module Data.Connection.Class (-  -- * Types-    Kan(..)-  , Conn()-  , Semilattice-  , Extremal-  , ConnFloat-  , ConnDouble-  , ConnInteger-  , ConnRational-  , ConnExtended-  -- * Connection L-  , ConnL-  , pattern ConnL-  , connL-  , swapL-  , embedL-  , ceiling-  , ceiling1-  , ceiling2-  , filterL-  , minimal-  , (\/)-  , glb-  -- * Connection R-  , ConnR-  , pattern ConnR-  , connR-  , swapR-  , floor-  , floor1-  , floor2-  , embedR-  , filterR-  , maximal-  , (/\)-  , lub-  -- * Connection k-  , Trip-  , pattern Conn-  , maybeL-  , maybeR-  , choice-  , strong-  , fmapped-  -- * Connection-  , Connection(..)-  , Triple-) where--import safe Control.Applicative (liftA2)-import safe Control.Category ((>>>))-import safe Data.Bool (bool)-import safe Data.Connection.Conn-import safe Data.Connection.Int-import safe Data.Connection.Word-import safe Data.Connection.Float-import safe Data.Connection.Double-import safe Data.Connection.Ratio-import safe Data.Functor.Contravariant-import safe Data.Functor.Identity-import safe Data.Monoid-import safe Data.Order-import safe Data.Order.Extended-import safe Data.Order.Interval-import safe Data.Word-import safe Data.Int-import safe GHC.TypeNats-import safe Numeric.Natural-import safe Prelude hiding (Bounded, floor, ceiling, fromInteger, fromRational)-import safe qualified Control.Category as C-import safe qualified Data.IntMap as IntMap-import safe qualified Data.IntSet as IntSet-import safe qualified Data.Map as Map-import safe qualified Data.Set as Set-import safe qualified Data.Finite as F-import safe qualified Data.Universe.Class as U-import safe qualified Prelude as P---- $setup--- >>> :set -XTypeApplications--- >>> import Data.Int--- >>> import Prelude hiding (Ord(..), Bounded, fromInteger, fromRational, RealFrac(..))--- >>> import qualified Prelude as P--- >>> :load Data.Connection----- | Semilattices.------ A complete is a partially ordered set in which every two elements have a unique join --- (least upper bound or supremum) and a unique meet (greatest lower bound or infimum). ------ These operations may in turn be defined by the lower and upper adjoints to the unique--- function /a -> (a, a)/.------ /Associativity/------ @--- x '\/' (y '\/' z) = (x '\/' y) '\/' z--- x '/\' (y '/\' z) = (x '/\' y) '/\' z--- @------ /Commutativity/------ @--- x '\/' y = y '\/' x--- x '/\' y = y '/\' x--- @------ /Idempotency/------ @--- x '\/' x = x--- x '/\' x = x--- @------ /Absorption/------ @--- (x '\/' y) '/\' y = y--- (x '/\' y) '\/' y = y--- @------ See < https://en.wikipedia.org/wiki/Absorption_law Absorption >.------ Note that distributivity is _not_ a requirement for a complete.--- However when /a/ is distributive we have;--- --- @--- 'glb' x y z = 'lub' x y z--- @------ See < https://en.wikipedia.org/wiki/Lattice_(order) >.----type Semilattice k a = Connection k (a, a) a--type Extremal k = Connection k ()--type ConnInteger k = Connection k (Maybe Integer)--type ConnFloat k = Connection k Float--type ConnDouble k = Connection k Double--type ConnRational k = Connection k Rational--type ConnExtended k a b = Connection k a (Extended b)---- | An < https://ncatlab.org/nlab/show/adjoint+string adjoint string > of Galois connections of length 2 or 3.----class (Preorder a, Preorder b) => Connection k a b where--    -- |-    ---    -- >>> range (conn @_ @Double @Float) pi-    -- (3.1415925,3.1415927)-    -- >>> range (conn @_ @Rational @Float) (1 :% 7)-    -- (0.14285713,0.14285715)-    -- >>> range (conn @_ @Rational @Float) (1 :% 8)-    -- (0.125,0.125)-    ---    conn :: Conn k a b---- | A constraint kind representing an <https://ncatlab.org/nlab/show/adjoint+triple adjoint triple> of Galois connections.----type Triple a b = (Connection 'L a b, Connection 'R a b)---------------------------------------------------------------------------- Connection L-------------------------------------------------------------------------- | A specialization of /conn/ to left-side connections.------ This is a convenience function provided primarily to avoid needing--- to enable /DataKinds/.----connL :: Connection 'L a b => ConnL a b-connL = conn @'L---- | Extract the center of a 'Trip' or upper half of a 'ConnL'.----embedL :: Connection 'L a b => b -> a-embedL = embed connL---- | Extract the ceiling of a 'Trip' or lower half of a 'ConnL'.------ > ceiling @a @a = id------ >>> ceiling @Rational @Float (0 :% 0)--- NaN--- >>> ceiling @Rational @Float (1 :% 0)--- Infinity--- >>> ceiling @Rational @Float (13 :% 10)--- 1.3000001----ceiling :: Connection 'L a b => a -> b-ceiling = lowerL connL---- | Lift a unary function over a 'ConnL'.----ceiling1 :: Connection 'L a b => (a -> a) -> b -> b-ceiling1 = lowerL1 connL---- | Lift a binary function over a 'ConnL'.----ceiling2 :: Connection 'L a b => (a -> a -> a) -> b -> b -> b-ceiling2 = lowerL2 connL---- | Obtain the principal filter in /B/ generated by an element of /A/.------ A subset /B/ of a lattice is an filter if and only if it is an upper set --- that is closed under finite meets, i.e., it is nonempty and for all --- /x/, /y/ in /B/, the element @x /\ y@ is also in /b/.------ /filterL/ and /filterR/ commute with /Down/:------ > filterL a b <=> filterR (Down a) (Down b)------ > filterL (Down a) (Down b) <=> filterR a b------ /filterL a/ is upward-closed for all /a/:------ > a <= b1 && b1 <= b2 => a <= b2------ > a1 <= b && inf a2 <= b => ceiling a1 /\ ceiling a2 <= b------ See <https://en.wikipedia.org/wiki/Filter_(mathematics)>----filterL :: Connection 'L a b => a -> b -> Bool-filterL a b = ceiling a <~ b---- | A minimal element of a preorder defined by a connection with '()'.------ 'minimal' needn't be unique, but we must have:------ > x <~ minimal => x ~~ minimal----minimal :: Extremal 'L a => a-minimal = lowerL connL ()--infixr 5 \/---- | Semigroup operation on a join-semilattice.------ > (\/) = curry $ lowerL forked----(\/) :: Semilattice 'L a => a -> a -> a-(\/) = curry $ lowerL connL---- | Greatest lower bound operator.------ > glb x x y = x--- > glb x y z = glb z x y--- > glb x x y = x--- > glb x y z = glb x z y--- > glb (glb x w y) w z = glb x w (glb y w z)------ >>> glb 1.0 9.0 7.0--- 7.0--- >>> glb 1.0 9.0 (0.0 / 0.0)--- 9.0--- >>> glb (fromList [1..3]) (fromList [3..5]) (fromList [5..7]) :: Set Int--- fromList [3,5]----glb :: Triple (a, a) a => a -> a -> a -> a-glb x y z = (x \/ y) /\ (y \/ z) /\ (z \/ x)-------------------------------------------------------------------------- Connection R-------------------------------------------------------------------------- | A specialization of /conn/ to right-side connections.------ This is a convenience function provided primarily to avoid needing--- to enable /DataKinds/.----connR :: Connection 'R a b => ConnR a b-connR = conn @'R---- | Extract the floor of a 'Trip' or upper half of a 'ConnL'.------ > floor @a @a = id------ >>> floor @Rational @Float (0 :% 0)--- NaN--- >>> floor @Rational @Float (1 :% 0)--- Infinity--- >>> floor @Rational @Float (13 :% 10)--- 1.3----floor :: Connection 'R a b => a -> b-floor = upperR connR---- | Lift a unary function over a 'ConnR'.----floor1 :: Connection 'R a b => (a -> a) -> b -> b-floor1 = upperR1 connR---- | Lift a binary function over a 'ConnR'.----floor2 :: Connection 'R a b => (a -> a -> a) -> b -> b -> b-floor2 = upperR2 connR---- | Extract the center of a 'Trip' or lower half of a 'ConnR'.----embedR :: Connection 'R a b => b -> a-embedR = embed connR---- | Obtain the principal ideal in /B/ generated by an element of /A/.------ A subset /B/ of a lattice is an ideal if and only if it is a lower set --- that is closed under finite joins, i.e., it is nonempty and for all --- /x/, /y/ in /B/, the element /x \/ y/ is also in /B/.------ /filterR a/ is downward-closed for all /a/:------ > a >= b1 && b1 >= b2 => a >= b2------ > a1 >= b && a2 >= b => floor a1 \/ floor a2 >= b------ See <https://en.wikipedia.org/wiki/Ideal_(order_theory)>----filterR :: Connection 'R a b => a -> b -> Bool-filterR a b = b <~ floor a---- | A maximal element of a preorder defined by a connection with '()'.------ 'maximal' needn't be unique, but we must have:------ > x >~ maximal => x ~~ maximal----maximal :: Extremal 'R a => a-maximal = upperR connR ()--infixr 6 /\ -- comment for the parser---- | Semigroup operation on a meet-semilattice.------ > (/\) = curry $ upperR forked----(/\) :: Semilattice 'R a => a -> a -> a-(/\) = curry $ upperR connR---- | Least upper bound operator.------ The order dual of 'glb'.------ >>> lub 1.0 9.0 7.0--- 7.0--- >>> lub 1.0 9.0 (0.0 / 0.0)--- 1.0----lub :: Triple (a, a) a => a -> a -> a -> a-lub x y z = (x /\ y) \/ (y /\ z) \/ (z /\ x)-------------------------------------------------------------------------- Connection------------------------------------------------------------------------maybeL :: Triple () b => Trip (Maybe a) (Either a b)-maybeL = trip f g h where-  f = maybe (Right minimal) Left-  g = either Just (const Nothing)-  h = maybe (Right maximal) Left--maybeR :: Triple () a => Trip (Maybe b) (Either a b)-maybeR = trip f g h where-  f = maybe (Left minimal) Right-  g = either (const Nothing) Just-  h = maybe (Left maximal) Right-------------------------------------------------------------------------- Instances------------------------------------------------------------------------instance Preorder a => Connection k a a where-  conn = C.id--instance Connection 'R Word16 Word8 where-  conn = swapR w08w16--instance Connection 'R Word32 Word8 where-  conn = swapR w08w32--instance Connection 'R Word32 Word16 where-  conn = swapR w16w32--instance Connection 'R Word64 Word8 where-  conn = swapR w08w64--instance Connection 'R Word64 Word16 where-  conn = swapR w16w64--instance Connection 'R Word64 Word32 where-  conn = swapR w32w64--instance Connection k Word Word64 where-  conn = wxxw64--instance Connection 'R Natural Word8 where-  conn = swapR w08nat--instance Connection 'R Natural Word16 where-  conn = swapR w16nat--instance Connection 'R Natural Word32 where-  conn = swapR w32nat--instance Connection 'R Natural Word64 where-  conn = swapR w64nat--instance Connection 'R Natural Word where-  conn = swapR wxxnat--instance Connection 'R Natural Integer where-  conn = swapR intnat--instance Connection 'R Int32 Int8 where-  conn = swapR i08i32--instance Connection 'R Int32 Int16 where-  conn = swapR i16i32--instance Connection 'R Int64 Int8 where-  conn = swapR i08i64--instance Connection 'R Int64 Int16 where-  conn = swapR i16i64--instance Connection 'R Int64 Int32 where-  conn = swapR i32i64--instance Connection k Int Int64 where-  conn = ixxi64--instance Connection 'R (Maybe Integer) Word8 where-  conn = swapR $ w08nat >>> natint--instance Connection 'R (Maybe Integer) Word16 where-  conn = swapR $ w16nat >>> natint--instance Connection 'R (Maybe Integer) Word32 where-  conn = swapR $ w32nat >>> natint--instance Connection 'R (Maybe Integer) Word64 where-  conn = swapR $ w64nat >>> natint--instance Connection 'R (Maybe Integer) Word where-  conn = swapR $ wxxnat >>> natint--instance Connection 'R (Maybe Integer) Natural where-  conn = swapR natint--instance Connection 'R (Maybe Integer) Int8 where-  conn = swapR i08int--instance Connection 'R (Maybe Integer) Int16 where-  conn = swapR i16int--instance Connection 'R (Maybe Integer) Int32 where-  conn = swapR i32int--instance Connection 'R (Maybe Integer) Int64 where-  conn = swapR i64int--instance Connection 'R (Maybe Integer) Int where-  conn = swapR ixxint--instance Connection 'R (Maybe Integer) Integer where-  -- | Provided as a shim for /RebindableSyntax/.-  -- Note that this instance will clip negative numbers to zero.-  conn = swapR $ intnat >>> natint--instance Connection k Int8 Word8 where-  conn = i08w08--instance Connection k Int16 Word16 where-  conn = i16w16--instance Connection k Int32 Word32 where-  conn = i32w32--instance Connection k Int64 Word64 where-  conn = i64w64--instance Connection k Int Word where-  conn = ixxwxx--instance Connection k Double Float where-  conn = f64f32--instance Connection k Rational Float where-  conn = ratf32--instance Connection k Rational Double where-  conn = ratf64--instance Connection k Rational (Extended Int8) where-  conn = rati08--instance Connection k Rational (Extended Int16) where-  conn = rati16--instance Connection k Rational (Extended Int32) where-  conn = rati32--instance Connection k Rational (Extended Int64) where-  conn = rati64--instance Connection k Rational (Extended Int) where-  conn = ratixx--instance Connection k Rational (Extended Integer) where-  conn = ratint--instance Connection k Float (Extended Int8) where-  conn = f32i08--instance Connection k Float (Extended Int16) where-  conn = f32i16--instance Connection 'L Float (Extended Int32) where-  conn = conn >>> fmapped (i16w16 >>> w16w32 >>> w32i32)--instance Connection 'L Float (Extended Int64) where-  conn = conn >>> fmapped (i16w16 >>> w16w64 >>> w64i64)--instance Connection 'L Float (Extended Int) where-  conn = conn >>> fmapped (i16w16 >>> w16wxx >>> swapL ixxwxx)--instance Connection k Double (Extended Int8) where-  conn = f64i08--instance Connection k Double (Extended Int16) where-  conn = f64i16--instance Connection k Double (Extended Int32) where-  conn = f64i32--instance Connection 'L Double (Extended Int64) where-  conn = conn >>> fmapped (i32w32 >>> w32w64 >>> w64i64)--instance Connection 'L Double (Extended Int) where-  conn = conn >>> fmapped (i32w32 >>> w32wxx >>> swapL ixxwxx)--instance Connection k a b => Connection k (Identity a) b where-  conn = Conn runIdentity Identity runIdentity >>> conn--instance Connection k a b => Connection k a (Identity b) where-  conn = conn >>> Conn Identity runIdentity Identity-------------------------------------------------------------------------- ------------------------------------------------------------------------fork :: a -> (a, a)-fork x = (x, x)--semilatticeN5 :: (Total a, Fractional a) => Conn k (a, a) a-semilatticeN5 = Conn (uncurry joinN5) fork (uncurry meetN5) where-  joinN5 x y = maybe (1 / 0) (bool y x . (>= EQ)) (pcompare x y)--  meetN5 x y = maybe (-1 / 0) (bool y x . (<= EQ)) (pcompare x y)--extremalN5 :: (Total a, Fractional a) => Conn k () a-extremalN5 = Conn (const $ -1/0) (const ()) (const $ 1/0)--semilatticeOrd :: (Total a) => Conn k (a, a) a-semilatticeOrd = Conn (uncurry max) fork (uncurry min)--extremalOrd :: (Total a, P.Bounded a) => Conn k () a-extremalOrd = Conn (const minBound) (const ()) (const maxBound)--instance Connection k ((),()) () where conn = semilatticeOrd-instance Connection k (Bool, Bool) Bool where conn = semilatticeOrd-instance Connection k () Bool where conn = extremalOrd-instance Connection k (Ordering, Ordering) Ordering  where conn = semilatticeOrd-instance Connection k () Ordering where conn = extremalOrd--instance Connection k (Word8, Word8) Word8 where conn = semilatticeOrd-instance Connection k () Word8 where conn = extremalOrd-instance Connection k (Word16, Word16) Word16 where conn = semilatticeOrd-instance Connection k () Word16 where conn = extremalOrd-instance Connection k (Word32, Word32) Word32 where conn = semilatticeOrd-instance Connection k () Word32 where conn = extremalOrd-instance Connection k (Word64, Word64) Word64 where conn = semilatticeOrd-instance Connection k () Word64 where conn = extremalOrd-instance Connection k (Word, Word) Word where conn = semilatticeOrd-instance Connection k () Word where conn = extremalOrd-instance Connection k (Natural, Natural) Natural where conn = semilatticeOrd--instance Connection k (Positive, Positive) Positive where conn = semilatticeN5-instance Connection k () Positive where-  conn = Conn (const $ 0 :% 1) (const ()) (const $ 1 :% 0)--instance Connection k (Int8, Int8) Int8 where conn = semilatticeOrd-instance Connection k () Int8 where conn = extremalOrd-instance Connection k (Int16, Int16) Int16 where conn = semilatticeOrd-instance Connection k () Int16 where conn = extremalOrd-instance Connection k (Int32, Int32) Int32 where conn = semilatticeOrd-instance Connection k () Int32 where conn = extremalOrd-instance Connection k (Int64, Int64) Int64 where conn = semilatticeOrd-instance Connection k () Int64 where conn = extremalOrd-instance Connection k (Int, Int) Int where conn = semilatticeOrd-instance Connection k () Int where conn = extremalOrd-instance Connection k (Integer, Integer) Integer where conn = semilatticeOrd--instance Connection k (Rational, Rational) Rational where conn = semilatticeN5-instance Connection k () Rational where-  conn = Conn (const $ -1 :% 0) (const ()) (const $ 1 :% 0)--instance Connection k (F.Finite n, F.Finite n) (F.Finite n) where conn = semilatticeOrd-instance KnownNat n => Connection k () (F.Finite n) where conn = extremalOrd--instance Connection k (Float, Float) Float where conn = semilatticeN5-instance Connection k () Float where conn = extremalN5--instance Connection k (Double, Double) Double where conn = semilatticeN5-instance Connection k () Double where conn = extremalN5--instance Total a => Connection k (Set.Set a, Set.Set a) (Set.Set a) where-  conn = Conn (uncurry Set.union) fork (uncurry Set.intersection)----instance (Total a, U.Finite a) => Connection k () (Set.Set a) where---  conn = Conn (const Set.empty) (const ()) (const $ Set.fromList U.universeF)-instance (Total a) => Connection 'L () (Set.Set a) where-  conn = ConnL (const Set.empty) (const ())--instance (Total a, U.Finite a) => Connection 'R () (Set.Set a) where-  conn = ConnR (const ()) (const $ Set.fromList U.universeF)--instance Connection k (IntSet.IntSet, IntSet.IntSet) IntSet.IntSet where-  conn = Conn (uncurry IntSet.union) fork (uncurry IntSet.intersection)--instance Connection k () IntSet.IntSet where-  conn = Conn (const IntSet.empty) (const ()) (const $ IntSet.fromList U.universeF)--instance (Total a, Connection 'L (b,b) b) => Connection 'L (Map.Map a b, Map.Map a b) (Map.Map a b) where-  conn = ConnL (uncurry $ Map.unionWith (\/)) fork--instance (Total a, Connection 'R (b,b) b) => Connection 'R (Map.Map a b, Map.Map a b) (Map.Map a b) where-  conn = ConnR fork (uncurry $ Map.intersectionWith (/\))--instance (Total a, Preorder b) => Connection 'L () (Map.Map a b) where-  conn = ConnL (const Map.empty) (const ()) --instance (Total a, U.Finite a, Connection 'R () b) => Connection 'R () (Map.Map a b) where-  conn = ConnR (const ()) (const . Map.fromList $ U.universeF `zip` repeat maximal)--instance Connection 'L (a,a) a => Connection 'L (IntMap.IntMap a, IntMap.IntMap a) (IntMap.IntMap a) where-  conn = ConnL (uncurry $ IntMap.unionWith (\/)) fork--instance Connection 'R (a,a) a => Connection 'R (IntMap.IntMap a, IntMap.IntMap a) (IntMap.IntMap a) where-  conn = ConnR fork (uncurry $ IntMap.intersectionWith (/\))--instance Preorder a => Connection 'L () (IntMap.IntMap a) where-  conn = ConnL (const IntMap.empty) (const ())--instance Connection 'R () a => Connection 'R () (IntMap.IntMap a) where-  conn = ConnR (const ()) (const . IntMap.fromList $ U.universeF `zip` repeat maximal)--joinMaybe :: Connection 'L (a, a) a => Maybe a -> Maybe a -> Maybe a-joinMaybe (Just x) (Just y) = Just (x \/ y)-joinMaybe u@(Just _) _ = u-joinMaybe _ u@(Just _) = u-joinMaybe Nothing Nothing = Nothing--meetMaybe :: Connection 'R (a, a) a => Maybe a -> Maybe a -> Maybe a-meetMaybe Nothing Nothing = Nothing-meetMaybe Nothing _ = Nothing-meetMaybe _ Nothing = Nothing-meetMaybe (Just x) (Just y) = Just (x /\ y)--instance Connection 'L (a, a) a => Connection 'L (Maybe a, Maybe a) (Maybe a) where-  conn = ConnL (uncurry joinMaybe) fork--instance Connection 'R (a, a) a => Connection 'R (Maybe a, Maybe a) (Maybe a) where-  conn = ConnR fork (uncurry meetMaybe)--instance Preorder a => Connection 'L () (Maybe a) where-  conn = ConnL (const Nothing) (const ())--instance Connection 'R () a => Connection 'R () (Maybe a) where-  conn = ConnR (const ()) (const $ Just maximal)--joinExtended :: Connection 'L (a, a) a => Extended a -> Extended a -> Extended a-joinExtended Top          _            = Top-joinExtended _            Top          = Top-joinExtended (Extended x) (Extended y) = Extended (x \/ y)-joinExtended Bottom       y            = y-joinExtended x            Bottom       = x--meetExtended :: Connection 'R (a, a) a => Extended a -> Extended a -> Extended a-meetExtended Top          y            = y-meetExtended x            Top          = x-meetExtended (Extended x) (Extended y) = Extended (x /\ y)-meetExtended Bottom       _            = Bottom-meetExtended _            Bottom       = Bottom--instance Connection 'L (a, a) a => Connection 'L (Extended a, Extended a) (Extended a) where-  conn = ConnL (uncurry joinExtended) fork--instance Connection 'R (a, a) a => Connection 'R (Extended a, Extended a) (Extended a) where-  conn = ConnR fork (uncurry meetExtended)--instance Preorder a => Connection k () (Extended a) where-  conn = Conn (const Bottom) (const ()) (const Top)--joinEither :: (Connection 'L (a, a) a, Connection 'L (b, b) b) => Either a b -> Either a b -> Either a b-joinEither (Right x) (Right y) = Right (x \/ y)-joinEither u@(Right _) _ = u-joinEither _ u@(Right _) = u-joinEither (Left x) (Left y) = Left (x \/ y)--meetEither :: (Connection 'R (a, a) a, Connection 'R (b, b) b) => Either a b -> Either a b -> Either a b-meetEither (Left x) (Left y) = Left (x /\ y)-meetEither l@(Left _) _ = l-meetEither _ l@(Left _) = l-meetEither (Right x) (Right y) = Right (x /\ y)---- | All minimal elements of the upper lattice cover all maximal elements of the lower lattice.-instance (Connection 'L (a,a) a, Connection 'L (b,b) b) => Connection 'L (Either a b, Either a b) (Either a b) where-  conn = ConnL (uncurry joinEither) fork--instance (Connection 'R (a,a) a, Connection 'R (b,b) b) => Connection 'R (Either a b, Either a b) (Either a b) where-  conn = ConnR fork (uncurry meetEither)--instance (Connection 'L () a, Preorder b) => Connection 'L () (Either a b) where-  conn = ConnL (const $ Left minimal) (const ())--instance (Preorder a, Connection 'R () b) => Connection 'R () (Either a b) where-  conn = ConnR (const ()) (const $ Right maximal)--joinTuple :: (Connection 'L (a, a) a, Connection 'L (b, b) b) => (a, b) -> (a, b) -> (a, b)-joinTuple (x1, y1) (x2, y2) = (x1 \/ x2, y1 \/ y2)--meetTuple :: (Connection 'R (a, a) a, Connection 'R (b, b) b) => (a, b) -> (a, b) -> (a, b)-meetTuple (x1, y1) (x2, y2) = (x1 /\ x2, y1 /\ y2)--instance (Triple (a, a) a, Triple (b, b) b) => Connection k ((a, b), (a, b)) (a, b) where-  conn = Conn (uncurry joinTuple) fork (uncurry meetTuple)--instance (Triple () a, Triple () b) => Connection k () (a, b) where-  conn = Conn (const (minimal, minimal)) (const ()) (const (maximal, maximal))--instance (U.Finite a, Triple (b, b) b) => Connection k (a -> b, a -> b) (a -> b) where-  conn = Conn (uncurry $ liftA2 (\/)) fork (uncurry $ liftA2 (/\))--instance (U.Finite a, Triple () b) => Connection k () (a -> b) where-  conn = Conn (const $ pure minimal) (const ()) (const $ pure maximal)--instance (U.Finite a, Triple (a, a) a) => Connection k (Endo a, Endo a) (Endo a) where-  conn = Conn (\(Endo x, Endo y) -> Endo $ x\/y) fork (\(Endo x, Endo y) -> Endo $ x/\y)--instance (U.Finite a, Triple () a) => Connection k () (Endo a) where-  conn = Conn (const $ Endo minimal) (const ()) (const $ Endo maximal)--instance (U.Finite a, Triple (b, b) b) => Connection k (Op b a, Op b a) (Op b a) where-  conn = Conn (\(Op x, Op y) -> Op $ x\/y) fork (\(Op x, Op y) -> Op $ x/\y)--instance (U.Finite a, Triple () b) => Connection k () (Op b a) where-  conn = Conn (const $ Op minimal) (const ()) (const $ Op maximal)--instance U.Finite a => Connection k (Predicate a, Predicate a) (Predicate a) where-  conn = Conn (\(Predicate x, Predicate y) -> Predicate $ x\/y) fork (\(Predicate x, Predicate y) -> Predicate $ x/\y)--instance U.Finite a => Connection k () (Predicate a) where-  conn = Conn (const $ Predicate minimal) (const ()) (const $ Predicate maximal)--{--instance (Applicative m, Connection k r) => Connection k (ContT r m a) where-  (<>) = liftA2 joinCont--instance (Applicative m, Connection k () r) => Connection k () (ContT r m a) where-  mempty = pure . ContT . const $ pure bottom--instance Monad m => Connection k (SelectT r m a) where-  (<>) = liftA2 joinSelect--instance MonadPlus m => Connection k () (SelectT r m a)) where-  bottom = pure empty-instance (Ord.Ord a, Preorder a, Preorder r, Finite r) => Preorder (Cont r a) where-  (ContT x) <~ (ContT y) = x `contLe` y--instance (Ord.Ord a, Preorder a, Preorder r, Finite r) => Preorder (Select r a) where-  (SelectT x) <~ (SelectT y) = x `contLe` y-instance (Applicative m, Total a, Preorder r, Finite r, Connection 'L r) => Connection 'L (ContT r m a, ContT r m a) (ContT r m a) where-  conn = ConnL (uncurry joinCont) fork--joinCont :: (Applicative m, Connection 'L (r,r) r) => ContT r m a -> ContT r m a -> ContT r m a-joinCont (ContT f) (ContT g) = ContT $ \p -> liftA2 join (f p) (g p) --instance (Monad m, Total a, Preorder r, Finite r, Extremal 'L r) => Connection 'L (SelectT r m a, SelectT r m a) (SelectT r m a) where-  conn = ConnL (uncurry joinSelect) fork--joinSelect :: (Monad m, Extremal 'L r) => SelectT r m b -> SelectT r m b -> SelectT r m b-joinSelect x y = branch x y >>= id-  where-    ifM c x y = c >>= \b -> if b then x else y-    branch x y = SelectT $ \p -> ifM ((~~ maximal) <$> p x) (pure x) (pure y)-  +{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ViewPatterns #-}++module Data.Connection.Class (+    -- * Conn+    Conn (),+    identity,++    -- * Connection k+    Triple,+    pattern Conn,+    ConnK,+    embed,+    extremal,+    lub,+    glb,+    half,+    midpoint,+    range,+    round,+    round1,+    round2,+    truncate,+    truncate1,+    truncate2,++    -- * Connection L+    Left,+    pattern ConnL,+    ConnL,+    connL,+    embedL,+    minimal,+    join,+    ceiling,+    ceiling1,+    ceiling2,++    -- * Connection R+    Right,+    pattern ConnR,+    ConnR,+    connR,+    embedR,+    maximal,+    meet,+    floor,+    floor1,+    floor2,++    -- * Combinators+    (>>>),+    (<<<),+    (/|\),+    (\|/),+    choice,+    strong,++    -- * Connection+    Kan (..),+    ConnInteger,+    ConnRational,+    ConnExtended,+    Connection (..),+) where++import safe Control.Category ((>>>))+import safe Data.Bool (bool)+import safe Data.Connection.Conn+import safe Data.Connection.Float+import safe Data.Connection.Int+import safe Data.Connection.Ratio+import safe Data.Connection.Word+import safe Data.Functor.Identity+import safe Data.Int+import safe qualified Data.IntMap as IntMap+import safe qualified Data.IntSet as IntSet+import safe qualified Data.Map as Map+import safe Data.Order+import safe Data.Order.Extended+import safe qualified Data.Set as Set+import safe Data.Word+import safe Numeric.Natural+import safe Prelude hiding (ceiling, floor, round, truncate)++-- $setup+-- >>> :set -XTypeApplications+-- >>> :set -XFlexibleContexts+-- >>> import GHC.Real (Ratio(..))+-- >>> import Data.Set (Set,fromList)+-- >>> :load Data.Connection+-- >>> import Prelude hiding (round, floor, ceiling, truncate)++type Left = Connection 'L++type Right = Connection 'R++-- | A constraint kind representing an <https://ncatlab.org/nlab/show/adjoint+triple adjoint triple> of Galois connections.+type Triple a b = (Left a b, Right a b)++-- | A constraint kind for 'Integer' conversions.+--+--  Usable in conjunction with /RebindableSyntax/:+--+--  > fromInteger = embedL . Just :: ConnInteger a => Integer -> a+type ConnInteger a = Left a (Maybe Integer)++-- | A constraint kind for 'Rational' conversions.+--+-- Usable in conjunction with /RebindableSyntax/:+--+--  > fromRational = round :: ConnRational a => Rational -> a+type ConnRational a = Triple Rational a++type ConnExtended a b = Triple a (Extended b)++-- | An < https://ncatlab.org/nlab/show/adjoint+string adjoint string > of Galois connections of length 2 or 3.+class (Preorder a, Preorder b) => Connection k a b where+    -- |+    --+    -- >>> range (conn @_ @Rational @Float) (22 :% 7)+    -- (3.142857,3.1428573)+    -- >>> range (conn @_ @Double @Float) pi+    -- (3.1415925,3.1415927)+    conn :: Conn k a b++infixr 3 \|/++-- | A preorder variant of 'Control.Arrow.|||'.+(\|/) :: Conn k c a -> Conn k c b -> Conn k c (Either a b)+f \|/ g = Conn Left (either id id) Right >>> f `choice` g++infixr 4 /|\++-- | A preorder variant of 'Control.Arrow.&&&'.+(/|\) :: Connection k (c, c) c => Conn k a c -> Conn k b c -> Conn k (a, b) c+f /|\ g = f `strong` g >>> conn++---------------------------------------------------------------------+-- Connection k+---------------------------------------------------------------------++-- | The canonical connections against a 'Bool'.+extremal :: Triple () a => Conn k a Bool+extremal = Conn f g h+  where+    g False = minimal+    g True = maximal++    f i+        | i ~~ minimal = False+        | otherwise = True++    h i+        | i ~~ maximal = True+        | otherwise = False++-- | Least upper bound operator.+--+-- The order dual of 'glb'.+--+-- >>> lub 1.0 9.0 7.0+-- 7.0+-- >>> lub 1.0 9.0 (0.0 / 0.0)+-- 1.0+lub :: Triple (a, a) a => a -> a -> a -> a+lub x y z = (x `meet` y) `join` (y `meet` z) `join` (z `meet` x)++-- | Greatest lower bound operator.+--+-- > glb x x y = x+-- > glb x y z = glb z x y+-- > glb x y z = glb x z y+-- > glb (glb x w y) w z = glb x w (glb y w z)+--+-- >>> glb 1.0 9.0 7.0+-- 7.0+-- >>> glb 1.0 9.0 (0.0 / 0.0)+-- 9.0+-- >>> glb (fromList [1..3]) (fromList [3..5]) (fromList [5..7]) :: Set Int+-- fromList [3,5]+glb :: Triple (a, a) a => a -> a -> a -> a+glb x y z = (x `join` y) `meet` (y `join` z) `meet` (z `join` x)++-- | Return the nearest value to x.+--+-- > round @a @a = id+--+-- If x lies halfway between two finite values, then return the value+-- with the larger absolute value (i.e. round away from zero).+--+-- See <https://en.wikipedia.org/wiki/Rounding>.+round :: forall a b. (Num a, Triple a b) => a -> b+round x = case pcompare halfR halfL of+    Just GT -> ceiling x+    Just LT -> floor x+    _ -> truncate x+  where+    halfR = x - lower (connR @a @b) x -- dist from lower bound+    halfL = upper (connL @a @b) x - x -- dist from upper bound++-- | Lift a unary function over a 'Conn'.+--+-- Results are rounded to the nearest value with ties away from 0.+round1 :: (Num a, Triple a b) => (a -> a) -> b -> b+round1 f x = round $ f (g x) where Conn _ g _ = connL+{-# INLINE round1 #-}++-- | Lift a binary function over a 'Conn'.+--+-- Results are rounded to the nearest value with ties away from 0.+--+-- Example avoiding loss-of-precision:+--+-- >>> f x y = (x + y) - x+-- >>> maxOdd32 = 1.6777215e7+-- >>> f maxOdd32 2.0 :: Float+-- 1.0+-- >>> round2 @Rational @Float f maxOdd32 2.0+-- 2.0+-- >>> maxOdd64 = 9.007199254740991e15+-- >>> f maxOdd64 2.0 :: Double+-- 1.0+-- >>> round2 @Rational @Double f maxOdd64 2.0+-- 2.0+round2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b+round2 f x y = round $ f (g x) (g y) where Conn _ g _ = connL+{-# INLINE round2 #-}++-- | Truncate towards zero.+--+-- > truncate @a @a = id+truncate :: (Num a, Triple a b) => a -> b+truncate x = if x >~ 0 then floor x else ceiling x++-- | Lift a unary function over a 'Conn'.+--+-- Results are truncated towards 0.+truncate1 :: (Num a, Triple a b) => (a -> a) -> b -> b+truncate1 f x = truncate $ f (g x) where Conn _ g _ = connL+{-# INLINE truncate1 #-}++-- | Lift a binary function over a 'Conn'.+--+-- Results are truncated towards 0.+truncate2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b+truncate2 f x y = truncate $ f (g x) (g y) where Conn _ g _ = connL+{-# INLINE truncate2 #-}++---------------------------------------------------------------------+-- Connection L+---------------------------------------------------------------------++-- | A specialization of /conn/ to left-side connections.+--+-- This is a convenience function provided primarily to avoid needing+-- to enable /DataKinds/.+connL :: Left a b => ConnL a b+connL = conn @ 'L++-- | Extract the center of a 'Conn' or upper half of a 'ConnL'.+embedL :: Left a b => b -> a+embedL = embed connL++-- | A minimal element of a preorder.+--+-- 'minimal' needn't be unique, but it must obey:+--+-- > x <~ minimal => x ~~ minimal+minimal :: Left () a => a+minimal = ceiling ()++infixr 5 `join`++-- | Semigroup operation on a join-lattice.+join :: Left (a, a) a => a -> a -> a+join = curry ceiling++-- | Extract the ceiling of a 'Conn' or lower half of a 'ConnL'.+--+-- > ceiling @a @a = id+-- > ceiling (x1 `join` a2) = ceiling x1 `join` ceiling x2+--+-- The latter law is the adjoint functor theorem for preorders.+--+-- >>> Data.Connection.ceiling @Rational @Float (0 :% 0)+-- NaN+-- >>> Data.Connection.ceiling @Rational @Float (1 :% 0)+-- Infinity+-- >>> Data.Connection.ceiling @Rational @Float (13 :% 10)+-- 1.3000001+ceiling :: Left a b => a -> b+ceiling = ceilingWith conn++-- | Lift a unary function over a 'ConnL'.+ceiling1 :: Left a b => (a -> a) -> b -> b+ceiling1 = ceilingWith1 conn++-- | Lift a binary function over a 'ConnL'.+ceiling2 :: Left a b => (a -> a -> a) -> b -> b -> b+ceiling2 = ceilingWith2 conn++---------------------------------------------------------------------+-- Connection R+---------------------------------------------------------------------++-- | A specialization of /conn/ to right-side connections.+--+-- This is a convenience function provided primarily to avoid needing+-- to enable /DataKinds/.+connR :: Right a b => ConnR a b+connR = conn @ 'R++-- | Extract the center of a 'ConnK' or lower half of a 'ConnR'.+embedR :: Right a b => b -> a+embedR = embed connR++-- | A maximal element of a preorder.+--+-- 'maximal' needn't be unique, but it must obey:+--+-- > x >~ maximal => x ~~ maximal+maximal :: Right () a => a+maximal = floor ()++infixr 6 `meet`++-- | Semigroup operation on a meet-lattice.+meet :: Right (a, a) a => a -> a -> a+meet = curry floor++-- | Extract the floor of a 'ConnK' or upper half of a 'ConnL'.+--+-- > floor @a @a = id+-- > floor (x1 `meet` x2) = floor x1 `meet` floor x2+--+-- The latter law is the adjoint functor theorem for preorders.+--+-- >>> Data.Connection.floor @Rational @Float (0 :% 0)+-- NaN+-- >>> Data.Connection.floor @Rational @Float (1 :% 0)+-- Infinity+-- >>> Data.Connection.floor @Rational @Float (13 :% 10)+-- 1.3+floor :: Right a b => a -> b+floor = floorWith conn++-- | Lift a unary function over a 'ConnR'.+floor1 :: Right a b => (a -> a) -> b -> b+floor1 = floorWith1 conn++-- | Lift a binary function over a 'ConnR'.+floor2 :: Right a b => (a -> a -> a) -> b -> b -> b+floor2 = floorWith2 conn++---------------------------------------------------------------------+-- Instances+---------------------------------------------------------------------++instance Preorder a => Connection k a a where conn = identity++instance Connection k ((), ()) () where conn = latticeOrd++instance Connection k () Bool where conn = bounded+instance Connection k Ordering Bool where conn = extremal+instance Connection k Word8 Bool where conn = extremal+instance Connection k Word16 Bool where conn = extremal+instance Connection k Word32 Bool where conn = extremal+instance Connection k Word64 Bool where conn = extremal+instance Connection k Word Bool where conn = extremal+instance Connection k Positive Bool where conn = extremal+instance Connection k Int8 Bool where conn = extremal+instance Connection k Int16 Bool where conn = extremal+instance Connection k Int32 Bool where conn = extremal+instance Connection k Int64 Bool where conn = extremal+instance Connection k Int Bool where conn = extremal+instance Connection k Rational Bool where conn = extremal+instance Connection k Float Bool where conn = extremal+instance Connection k Double Bool where conn = extremal+instance Connection k (Bool, Bool) Bool where conn = latticeOrd++instance Connection k () Ordering where conn = bounded+instance Connection k (Ordering, Ordering) Ordering where conn = latticeOrd++instance Connection k () Word8 where conn = bounded+instance Connection 'L Int8 Word8 where conn = i08w08+instance Connection k (Word8, Word8) Word8 where conn = latticeOrd++instance Connection k () Word16 where conn = bounded+instance Connection 'L Word8 Word16 where conn = w08w16+instance Connection 'L Int8 Word16 where conn = i08w16+instance Connection 'L Int16 Word16 where conn = i16w16+instance Connection k (Word16, Word16) Word16 where conn = latticeOrd++instance Connection k () Word32 where conn = bounded+instance Connection 'L Word8 Word32 where conn = w08w32+instance Connection 'L Word16 Word32 where conn = w16w32+instance Connection 'L Int8 Word32 where conn = i08w32+instance Connection 'L Int16 Word32 where conn = i16w32+instance Connection 'L Int32 Word32 where conn = i32w32+instance Connection k (Word32, Word32) Word32 where conn = latticeOrd++instance Connection k () Word64 where conn = bounded+instance Connection 'L Word8 Word64 where conn = w08w64+instance Connection 'L Word16 Word64 where conn = w16w64+instance Connection 'L Word32 Word64 where conn = w32w64+instance Connection 'L Int8 Word64 where conn = i08w64+instance Connection 'L Int16 Word64 where conn = i16w64+instance Connection 'L Int32 Word64 where conn = i32w64+instance Connection 'L Int64 Word64 where conn = i64w64+instance Connection 'L Int Word64 where conn = ixxw64+instance Connection k (Word64, Word64) Word64 where conn = latticeOrd++instance Connection k () Word where conn = bounded+instance Connection 'L Word8 Word where conn = w08wxx+instance Connection 'L Word16 Word where conn = w16wxx+instance Connection 'L Word32 Word where conn = w32wxx+instance Connection k Word64 Word where conn = w64wxx+instance Connection 'L Int8 Word where conn = i08wxx+instance Connection 'L Int16 Word where conn = i16wxx+instance Connection 'L Int32 Word where conn = i32wxx+instance Connection 'L Int64 Word where conn = i64wxx+instance Connection 'L Int Word where conn = ixxwxx+instance Connection k (Word, Word) Word where conn = latticeOrd++instance Connection 'L () Natural where conn = ConnL (const 0) (const ())+instance Connection 'L Word8 Natural where conn = w08nat+instance Connection 'L Word16 Natural where conn = w16nat+instance Connection 'L Word32 Natural where conn = w32nat+instance Connection 'L Word64 Natural where conn = w64nat+instance Connection 'L Word Natural where conn = wxxnat+instance Connection 'L Int8 Natural where conn = i08nat+instance Connection 'L Int16 Natural where conn = i16nat+instance Connection 'L Int32 Natural where conn = i32nat+instance Connection 'L Int64 Natural where conn = i64nat+instance Connection 'L Int Natural where conn = ixxnat+instance Connection 'L Integer Natural where conn = intnat+instance Connection k (Natural, Natural) Natural where conn = latticeOrd++instance Connection k () Positive where+    conn = Conn (const $ 0 :% 1) (const ()) (const $ 1 :% 0)+instance Connection k (Positive, Positive) Positive where conn = latticeN5++instance Connection k () Int8 where conn = bounded+instance Connection k (Int8, Int8) Int8 where conn = latticeOrd+instance Connection k () Int16 where conn = bounded+instance Connection k (Int16, Int16) Int16 where conn = latticeOrd+instance Connection k () Int32 where conn = bounded+instance Connection k (Int32, Int32) Int32 where conn = latticeOrd+instance Connection k () Int64 where conn = bounded+instance Connection k (Int64, Int64) Int64 where conn = latticeOrd+instance Connection k () Int where conn = bounded+instance Connection k (Int, Int) Int where conn = latticeOrd+instance Connection k (Integer, Integer) Integer where conn = latticeOrd++instance Connection k () Rational where+    conn = Conn (const $ -1 :% 0) (const ()) (const $ 1 :% 0)+instance Connection k (Rational, Rational) Rational where conn = latticeN5++instance Connection k () Float where conn = extremalN5+instance Connection k Double Float where conn = f64f32+instance Connection k Rational Float where conn = ratf32+instance Connection k (Float, Float) Float where conn = latticeN5++instance Connection k () Double where conn = extremalN5+instance Connection k Rational Double where conn = ratf64+instance Connection k (Double, Double) Double where conn = latticeN5++instance Connection 'L Word8 (Maybe Int16) where conn = w08i16+instance Connection 'L Int8 (Maybe Int16) where conn = i08i16++instance Connection 'L Word8 (Maybe Int32) where conn = w08i32+instance Connection 'L Word16 (Maybe Int32) where conn = w16i32+instance Connection 'L Int8 (Maybe Int32) where conn = i08i32+instance Connection 'L Int16 (Maybe Int32) where conn = i16i32++instance Connection 'L Word8 (Maybe Int64) where conn = w08i64+instance Connection 'L Word16 (Maybe Int64) where conn = w16i64+instance Connection 'L Word32 (Maybe Int64) where conn = w32i64+instance Connection 'L Int8 (Maybe Int64) where conn = i08i64+instance Connection 'L Int16 (Maybe Int64) where conn = i16i64+instance Connection 'L Int32 (Maybe Int64) where conn = i32i64++instance Connection 'L Word8 (Maybe Int) where conn = w08ixx+instance Connection 'L Word16 (Maybe Int) where conn = w16ixx+instance Connection 'L Word32 (Maybe Int) where conn = w32ixx+instance Connection 'L Int8 (Maybe Int) where conn = i08ixx+instance Connection 'L Int16 (Maybe Int) where conn = i16ixx+instance Connection 'L Int32 (Maybe Int) where conn = i32ixx+instance Connection k Int64 Int where conn = i64ixx++instance Connection 'L Word8 (Maybe Integer) where conn = w08int+instance Connection 'L Word16 (Maybe Integer) where conn = w16int+instance Connection 'L Word32 (Maybe Integer) where conn = w32int+instance Connection 'L Word64 (Maybe Integer) where conn = w64int+instance Connection 'L Word (Maybe Integer) where conn = wxxint+instance Connection 'L Natural (Maybe Integer) where conn = natint++instance Connection 'L Int8 (Maybe Integer) where conn = i08int+instance Connection 'L Int16 (Maybe Integer) where conn = i16int+instance Connection 'L Int32 (Maybe Integer) where conn = i32int+instance Connection 'L Int64 (Maybe Integer) where conn = i64int+instance Connection 'L Int (Maybe Integer) where conn = ixxint++{-+instance Connection 'L Integer (Maybe Integer) where+  -- | Provided as a shim for /RebindableSyntax/.+  -- Note that this instance will clip negative numbers to zero.+conn = swapR $ intnat >>> natint+-}++instance Connection k Rational (Extended Int8) where conn = rati08+instance Connection k Rational (Extended Int16) where conn = rati16+instance Connection k Rational (Extended Int32) where conn = rati32+instance Connection k Rational (Extended Int64) where conn = rati64+instance Connection k Rational (Extended Int) where conn = ratixx+instance Connection k Rational (Extended Integer) where conn = ratint++-- | All 'Data.Int.Int08' values are exactly representable in a 'Float'.+instance Connection k Float (Extended Int8) where conn = f32i08++-- | All 'Data.Int.Int16' values are exactly representable in a 'Float'.+instance Connection k Float (Extended Int16) where conn = f32i16++-- | All 'Data.Int.Int08' values are exactly representable in a 'Double'.+instance Connection k Double (Extended Int8) where conn = f64i08++-- | All 'Data.Int.Int16' values are exactly representable in a 'Double'.+instance Connection k Double (Extended Int16) where conn = f64i16++-- | All 'Data.Int.Int32' values are exactly representable in a 'Double'.+instance Connection k Double (Extended Int32) where conn = f64i32++instance Connection k a b => Connection k (Identity a) b where+    conn = Conn runIdentity Identity runIdentity >>> conn++instance Connection k a b => Connection k a (Identity b) where+    conn = conn >>> Conn Identity runIdentity Identity++instance (Triple () a, Triple () b) => Connection k () (a, b) where+    conn = Conn (const (minimal, minimal)) (const ()) (const (maximal, maximal))++instance Preorder a => Connection 'L () (Maybe a) where+    conn = ConnL (const Nothing) (const ())++instance Right () a => Connection 'R () (Maybe a) where+    conn = ConnR (const ()) (const $ Just maximal)++instance Preorder a => Connection k () (Extended a) where+    conn = Conn (const Bottom) (const ()) (const Top)++instance (Left () a, Preorder b) => Connection 'L () (Either a b) where+    conn = ConnL (const $ Left minimal) (const ())++instance (Preorder a, Right () b) => Connection 'R () (Either a b) where+    conn = ConnR (const ()) (const $ Right maximal)++instance (Preorder a, Triple () b) => Connection k (Maybe a) (Either a b) where+    conn = maybeL++instance (Triple () a, Preorder b) => Connection k (Maybe b) (Either a b) where+    conn = maybeR++instance (Total a) => Connection 'L () (Set.Set a) where+    conn = ConnL (const Set.empty) (const ())++instance Total a => Connection k (Set.Set a, Set.Set a) (Set.Set a) where+    conn = Conn (uncurry Set.union) fork (uncurry Set.intersection)++instance Connection 'L () IntSet.IntSet where+    conn = ConnL (const IntSet.empty) (const ())++instance Connection k (IntSet.IntSet, IntSet.IntSet) IntSet.IntSet where+    conn = Conn (uncurry IntSet.union) fork (uncurry IntSet.intersection)++instance (Total a, Preorder b) => Connection 'L () (Map.Map a b) where+    conn = ConnL (const Map.empty) (const ())++instance (Total a, Left (b, b) b) => Connection 'L (Map.Map a b, Map.Map a b) (Map.Map a b) where+    conn = ConnL (uncurry $ Map.unionWith join) fork++instance (Total a, Right (b, b) b) => Connection 'R (Map.Map a b, Map.Map a b) (Map.Map a b) where+    conn = ConnR fork (uncurry $ Map.intersectionWith meet)++instance Preorder a => Connection 'L () (IntMap.IntMap a) where+    conn = ConnL (const IntMap.empty) (const ())++instance Left (a, a) a => Connection 'L (IntMap.IntMap a, IntMap.IntMap a) (IntMap.IntMap a) where+    conn = ConnL (uncurry $ IntMap.unionWith join) fork++instance Right (a, a) a => Connection 'R (IntMap.IntMap a, IntMap.IntMap a) (IntMap.IntMap a) where+    conn = ConnR fork (uncurry $ IntMap.intersectionWith meet)++-- Internal++-------------------------++fork :: a -> (a, a)+fork x = (x, x)++bounded :: Bounded a => Conn k () a+bounded = Conn (const minBound) (const ()) (const maxBound)++latticeN5 :: (Total a, Fractional a) => Conn k (a, a) a+latticeN5 = Conn (uncurry joinN5) fork (uncurry meetN5)+  where+    joinN5 x y = maybe (1 / 0) (bool y x . (>= EQ)) (pcompare x y)++    meetN5 x y = maybe (-1 / 0) (bool y x . (<= EQ)) (pcompare x y)++extremalN5 :: (Total a, Fractional a) => Conn k () a+extremalN5 = Conn (const $ -1 / 0) (const ()) (const $ 1 / 0)++latticeOrd :: (Total a) => Conn k (a, a) a+latticeOrd = Conn (uncurry max) fork (uncurry min)++maybeL :: Triple () b => Conn k (Maybe a) (Either a b)+maybeL = Conn f g h+  where+    f = maybe (Right minimal) Left+    g = either Just (const Nothing)+    h = maybe (Right maximal) Left++maybeR :: Triple () a => Conn k (Maybe b) (Either a b)+maybeR = Conn f g h+  where+    f = maybe (Left minimal) Right+    g = either (const Nothing) Just+    h = maybe (Left maximal) Right++{-+instance (Triple (a, a) a, Triple (b, b) b) => Connection k ((a, b), (a, b)) (a, b) where+  conn = Conn (uncurry joinTuple) fork (uncurry meetTuple)++instance Left (a, a) a => Connection 'L (Maybe a, Maybe a) (Maybe a) where+  conn = ConnL (uncurry joinMaybe) fork++instance Right (a, a) a => Connection 'R (Maybe a, Maybe a) (Maybe a) where+  conn = ConnR fork (uncurry meetMaybe)++instance Left (a, a) a => Connection 'L (Extended a, Extended a) (Extended a) where+  conn = ConnL (uncurry joinExtended) fork++instance Right (a, a) a => Connection 'R (Extended a, Extended a) (Extended a) where+  conn = ConnR fork (uncurry meetExtended)++-- | All minimal elements of the upper lattice cover all maximal elements of the lower lattice.+instance (Left (a, a) a, Left (b, b) b) => Connection 'L (Either a b, Either a b) (Either a b) where+  conn = ConnL (uncurry joinEither) fork++instance (Right (a, a) a, Right (b, b) b) => Connection 'R (Either a b, Either a b) (Either a b) where+  conn = ConnR fork (uncurry meetEither)++joinMaybe :: Connection 'L (a, a) a => Maybe a -> Maybe a -> Maybe a+joinMaybe (Just x) (Just y) = Just (x `join` y)+joinMaybe u@(Just _) _ = u+joinMaybe _ u@(Just _) = u+joinMaybe Nothing Nothing = Nothing++meetMaybe :: Connection 'R (a, a) a => Maybe a -> Maybe a -> Maybe a+meetMaybe Nothing Nothing = Nothing+meetMaybe Nothing _ = Nothing+meetMaybe _ Nothing = Nothing+meetMaybe (Just x) (Just y) = Just (x `meet` y)++joinExtended :: Connection 'L (a, a) a => Extended a -> Extended a -> Extended a+joinExtended Top          _            = Top+joinExtended _            Top          = Top+joinExtended (Extended x) (Extended y) = Extended (x `join` y)+joinExtended Bottom       y            = y+joinExtended x            Bottom       = x++meetExtended :: Connection 'R (a, a) a => Extended a -> Extended a -> Extended a+meetExtended Top          y            = y+meetExtended x            Top          = x+meetExtended (Extended x) (Extended y) = Extended (x `meet` y)+meetExtended Bottom       _            = Bottom+meetExtended _            Bottom       = Bottom++joinEither :: (Connection 'L (a, a) a, Connection 'L (b, b) b) => Either a b -> Either a b -> Either a b+joinEither (Right x) (Right y) = Right (x `join` y)+joinEither u@(Right _) _ = u+joinEither _ u@(Right _) = u+joinEither (Left x) (Left y) = Left (x `join` y)++meetEither :: (Connection 'R (a, a) a, Connection 'R (b, b) b) => Either a b -> Either a b -> Either a b+meetEither (Left x) (Left y) = Left (x `meet` y)+meetEither l@(Left _) _ = l+meetEither _ l@(Left _) = l+meetEither (Right x) (Right y) = Right (x `meet` y)++joinTuple :: (Connection 'L (a, a) a, Connection 'L (b, b) b) => (a, b) -> (a, b) -> (a, b)+joinTuple (x1, y1) (x2, y2) = (x1 `join` x2, y1 `join` y2)++meetTuple :: (Connection 'R (a, a) a, Connection 'R (b, b) b) => (a, b) -> (a, b) -> (a, b)+meetTuple (x1, y1) (x2, y2) = (x1 `meet` x2, y1 `meet` y2) -}
src/Data/Connection/Conn.hs view
@@ -1,137 +1,246 @@-{-# Language TypeFamilies        #-}-{-# Language TypeApplications    #-}-{-# Language AllowAmbiguousTypes #-}-{-# Language ConstraintKinds     #-}-{-# Language Safe                #-}-{-# Language DeriveFunctor       #-}-{-# Language DeriveGeneric       #-}-{-# Language DataKinds           #-}-{-# Language ViewPatterns        #-}-{-# Language PatternSynonyms     #-}-{-# Language RankNTypes          #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ViewPatterns #-}+ module Data.Connection.Conn (-  -- * Conn-    Kan(..)-  , Conn()-  , embed-  -- ** Trip-  , type Trip-  , pattern Conn-  , trip-  , range-  -- ** ConnL-  , type ConnL-  , pattern ConnL-  , swapL-  , downL-  , unitL-  , counitL-  , lowerL-  , lowerL1-  , lowerL2-  , upperL1-  , upperL2-  -- ** ConnR-  , type ConnR-  , pattern ConnR-  , swapR-  , downR-  , unitR-  , counitR-  , upperR-  , upperR1-  , upperR2-  , lowerR1-  , lowerR2-  -- * Connections-  , choice-  , strong-  , fmapped+    -- * Conn+    Kan (..),+    Conn (),+    pattern Conn,+    embed,+    range,+    identity,++    -- * Connection k+    ConnK,+    half,+    midpoint,+    roundWith,+    roundWith1,+    roundWith2,+    truncateWith,+    truncateWith1,+    truncateWith2,++    -- * Connection L+    ConnL,+    pattern ConnL,+    upL,+    downL,+    swapL,+    counit,+    upper,+    upper1,+    upper2,+    filterWith,+    ceilingWith,+    ceilingWith1,+    ceilingWith2,++    -- * Connection R+    ConnR,+    pattern ConnR,+    upR,+    downR,+    swapR,+    unit,+    lower,+    lower1,+    lower2,+    idealWith,+    floorWith,+    floorWith1,+    floorWith2,++    -- * Combinators+    (>>>),+    (<<<),+    choice,+    strong, ) where  import safe Control.Arrow-import safe Control.Category (Category)+import safe Control.Category (Category, (<<<), (>>>))+import safe qualified Control.Category as C import safe Data.Bifunctor (bimap) import safe Data.Order-import safe Prelude hiding (Ord(..), Bounded)-import safe qualified Control.Category as C+import safe Prelude hiding (Ord (..)) --- | A data kind distinguishing the chirality of a Kan extension.------ Here it serves to distinguish the directionality of a preorder:------ * /L/-tagged types are 'upwards-directed'+-- $setup+-- >>> :set -XTypeApplications+-- >>> import Data.Int+-- >>> import Data.Ord (Down(..))+-- >>> import GHC.Real (Ratio(..))+-- >>> :load Data.Connection+-- >>> ratf32 = conn @_ @Rational @Float+-- >>> f64f32 = conn @_ @Double @Float++-- | A data kind distinguishing the directionality of a Galois connection: ----- * /R/-tagged types are 'downwards-directed'+-- * /L/-tagged types are low / increasing (e.g. 'Data.Connection.Class.minimal', 'Data.Connection.Class.upper', 'Data.Connection.Class.ceiling', 'Data.Connection.Class.join') --+-- * /R/-tagged types are high / decreasing (e.g. 'Data.Connection.Class.maximal', 'Data.Connection.Class.lower', 'Data.Connection.Class.floor', 'Data.Connection.Class.meet') data Kan = L | R  -- | An < https://ncatlab.org/nlab/show/adjoint+string adjoint string > of Galois connections of length 2 or 3. ---data Conn (k :: Kan) a b = Conn_ (a -> (b , b)) (b -> a)+-- Connections have many nice properties wrt numerical conversion:+--+-- >>> range (conn @_ @Rational @Float) (1 :% 8) -- eighths are exactly representable in a float+-- (0.125,0.125)+-- >>> range (conn @_ @Rational @Float) (1 :% 7) -- sevenths are not+-- (0.14285713,0.14285715)+data Conn (k :: Kan) a b = Galois (a -> (b, b)) (b -> a)  instance Category (Conn k) where-  id = Conn_ (id &&& id) id+    id = identity+    {-# INLINE id #-} -  Conn_ f1 g1 . Conn_ f2 g2 = Conn_ ((fst.f1).(fst.f2) &&& (snd.f1).(snd.f2)) (g2 . g1)+    Galois f1 g1 . Galois f2 g2 = Galois ((fst . f1) . (fst . f2) &&& (snd . f1) . (snd . f2)) (g2 . g1)+    {-# INLINE (.) #-} --- | Obtain the center of a /Trip/, upper half of a /ConnL/, or the lower half of a /ConnR/.+-- | Obtain a /Conn/ from an adjoint triple of monotone functions. ---embed :: Conn k a b -> b -> a-embed (Conn_ _ g) = g+--  This is a view pattern for an arbitrary 'Conn'. When applied to a 'ConnL'+--  or 'ConnR', the two functions of type @a -> b@ returned will be identical.+--+--  /Caution/: /Conn f g h/ must obey \(f \dashv g \dashv h\). This condition is not checked.+--+--  For detailed properties see 'Data.Connection.Property'.+pattern Conn :: (a -> b) -> (b -> a) -> (a -> b) -> Conn k a b+pattern Conn f g h <- (embed &&& _1 &&& _2 -> (g, (h, f))) where Conn f g h = Galois (h &&& f) g +{-# COMPLETE Conn #-}+ -- Internal floor function. When \(f \dashv g \dashv h \) this is h. _1 :: Conn k a b -> a -> b-_1 (Conn_ f _) = fst . f+_1 (Galois f _) = fst . f+{-# INLINE _1 #-}  -- Internal ceiling function. When \(f \dashv g \dashv h \) this is f. _2 :: Conn k a b -> a -> b-_2 (Conn_ f _) = snd . f+_2 (Galois f _) = snd . f+{-# INLINE _2 #-} +-- | The identity 'Conn'.+identity :: Conn k a a+identity = Galois (id &&& id) id+{-# INLINE identity #-}++-- | Obtain the center of a 'ConnK', upper adjoint of a 'ConnL', or lower adjoint of a 'ConnR'.+embed :: Conn k a b -> b -> a+embed (Galois _ g) = g+{-# INLINE embed #-}++-- | Obtain the upper and/or lower adjoints of a connection.+--+-- > range c = floorWith c &&& ceilingWith c+--+-- >>> range f64f32 pi+-- (3.1415925,3.1415927)+-- >>> range f64f32 (0/0)+-- (NaN,NaN)+range :: Conn k a b -> a -> (b, b)+range (Galois f _) = f+{-# INLINE range #-}+ ------------------------------------------------------------------------ Trip+-- ConnK ---------------------------------------------------------------------  -- | An <https://ncatlab.org/nlab/show/adjoint+triple adjoint triple> of Galois connections. -- -- An adjoint triple is a chain of connections of length 3: ----- \(f \dashv g \dashv h \) +-- \(f \dashv g \dashv h \) -- -- For detailed properties see 'Data.Connection.Property'.+type ConnK a b = forall k. Conn k a b++-- | Determine which half of the interval between 2 representations of /a/ a particular value lies. ---type Trip a b = forall k. Conn k a b+-- @ 'half' t x = 'pcompare' (x - 'lower' t x) ('upper' t x - x) @+--+-- >>> maybe False (== EQ) $ half f64f32 (midpoint f64f32 pi)+-- True+half :: (Num a, Preorder a) => ConnK a b -> a -> Maybe Ordering+half c x = pcompare (x - lower c x) (upper c x - x)+{-# INLINE half #-} --- | A view pattern for an arbitrary (left or right) 'Conn'.+-- | Return the midpoint of the interval containing x. ----- /Caution/: /Conn f g h/ must obey \(f \dashv g \dashv h\). This condition is not checked.+-- >>> pi - midpoint f64f32 pi+-- 3.1786509424591713e-8+midpoint :: Fractional a => ConnK a b -> a -> a+midpoint c x = lower c x / 2 + upper c x / 2+{-# INLINE midpoint #-}++-- | Return the nearest value to x. ----- For detailed properties see 'Data.Connection.Property'.+-- > roundWith identity = id ---pattern Conn :: (a -> b) -> (b -> a) -> (a -> b) -> Conn k a b-pattern Conn f g h <- (embed &&& _1 &&& _2 -> (g, (h, f)))-  where Conn f g h = Conn_ (h &&& f) g-{-# COMPLETE Conn #-}+-- If x lies halfway between two finite values, then return the value+-- with the larger absolute value (i.e. round away from zero).+--+-- See <https://en.wikipedia.org/wiki/Rounding>.+roundWith :: forall a b. (Num a, Preorder a) => ConnK a b -> a -> b+roundWith c x = case half c x of+    Just GT -> ceilingWith c x+    Just LT -> floorWith c x+    _ -> truncateWith c x+{-# INLINE roundWith #-} --- | Obtain a /forall k. Conn k/ from an adjoint triple of monotone functions.+-- | Lift a unary function over a 'ConnK'. ----- /Caution/: @Conn f g h@ must obey \(f \dashv g \dashv h\). This condition is not checked.+-- Results are rounded to the nearest value with ties away from 0.+roundWith1 :: (Num a, Preorder a) => ConnK a b -> (a -> a) -> b -> b+roundWith1 c f x = roundWith c $ f (g x) where Conn _ g _ = c+{-# INLINE roundWith1 #-}++-- | Lift a binary function over a 'ConnK'. ---trip :: (a -> b) -> (b -> a) -> (a -> b) -> Trip a b-trip f g h = Conn_ (h &&& f) g+-- Results are rounded to the nearest value with ties away from 0.+--+-- Example avoiding loss-of-precision:+--+-- >>> f x y = (x + y) - x+-- >>> maxOdd32 = 1.6777215e7+-- >>> f maxOdd32 2.0 :: Float+-- 1.0+-- >>> roundWith2 ratf32 f maxOdd32 2.0+-- 2.0+roundWith2 :: (Num a, Preorder a) => ConnK a b -> (a -> a -> a) -> b -> b -> b+roundWith2 c f x y = roundWith c $ f (g x) (g y) where Conn _ g _ = c+{-# INLINE roundWith2 #-} --- | Obtain the lower and upper functions from a 'Trip'.+-- | Truncate towards zero. ----- > range c = upperR c &&& lowerL c+-- > truncateWith identity = id+truncateWith :: (Num a, Preorder a) => ConnK a b -> a -> b+truncateWith c x = if x >~ 0 then floorWith c x else ceilingWith c x+{-# INLINE truncateWith #-}++-- | Lift a unary function over a 'ConnK'. ----- >>> range f64f32 pi--- (3.1415925,3.1415927)--- >>> range f64f32 (0/0)--- (NaN,NaN)+-- Results are truncated towards zero. ---range :: Trip a b -> a -> (b, b)-range c = upperR c &&& lowerL c +-- > truncateWith1 identity = id+truncateWith1 :: (Num a, Preorder a) => ConnK a b -> (a -> a) -> b -> b+truncateWith1 c f x = truncateWith c $ f (g x) where Conn _ g _ = c+{-# INLINE truncateWith1 #-} +truncateWith2 :: (Num a, Preorder a) => ConnK a b -> (a -> a -> a) -> b -> b -> b+truncateWith2 c f x y = truncateWith c $ f (g x) (g y) where Conn _ g _ = c+{-# INLINE truncateWith2 #-}+ --------------------------------------------------------------------- -- ConnL ---------------------------------------------------------------------@@ -142,7 +251,7 @@ -- is an adjunction in the category of preorders. -- -- Each side of the connection may be defined in terms of the other:--- +-- --  \( g(x) = \sup \{y \in E \mid f(y) \leq x \} \) -- --  \( f(x) = \inf \{y \in E \mid g(y) \geq x \} \)@@ -150,94 +259,122 @@ -- For further information see 'Data.Connection.Property'. -- -- /Caution/: Monotonicity is not checked.--- type ConnL = Conn 'L  -- | A view pattern for a 'ConnL'. -- -- /Caution/: /ConnL f g/ must obey \(f \dashv g \). This condition is not checked.--- pattern ConnL :: (a -> b) -> (b -> a) -> ConnL a b-pattern ConnL f g <- (_2 &&& embed -> (f, g)) where ConnL f g = Conn_ (f &&& f) g+pattern ConnL f g <- (_2 &&& embed -> (f, g)) where ConnL f g = Galois (f &&& f) g+ {-# COMPLETE ConnL #-} --- | Witness to the symmetry between 'ConnL' and 'ConnR'.------ > swapL . swapR = id--- > swapR . swapL = id+-- | Convert an inverted 'ConnL' to a 'ConnL'. ---swapL :: ConnR a b -> ConnL b a-swapL (ConnR f g) = ConnL f g+-- > upL . downL = downL . upL = id+upL :: ConnL (Down a) (Down b) -> ConnL b a+upL (ConnL f g) = ConnL g' f'+  where+    f' x = let (Down y) = f (Down x) in y+    g' x = let (Down y) = g (Down x) in y+{-# INLINE upL #-} --- | Convert an arbitrary 'Conn' to an inverted 'ConnL'.+-- | Convert a 'ConnL' to an inverted 'ConnL'. ----- >>> unitL (downL $ conn @_ @() @Ordering) (Down LT)+-- >>> upper (downL $ conn @_ @() @Ordering) (Down LT) -- Down LT--- >>> unitL (downL $ conn @_ @() @Ordering) (Down GT)+-- >>> upper (downL $ conn @_ @() @Ordering) (Down GT) -- Down LT--- downL :: ConnL a b -> ConnL (Down b) (Down a) downL (ConnL f g) = ConnL (\(Down x) -> Down $ g x) (\(Down x) -> Down $ f x)+{-# INLINE downL #-} --- | Round trip through a connection.------ > unitL c = upperL1 c id = embed c . lowerL c--- > x <= unitL c x--- --- >>> compare pi $ unitL f64f32 pi--- LT+-- | Witness to the symmetry between 'ConnL' and 'ConnR'. ---unitL :: ConnL a b -> a -> a-unitL c = upperL1 c id+-- > swapL . swapR = id+-- > swapR . swapL = id+swapL :: ConnR a b -> ConnL b a+swapL (ConnR f g) = ConnL f g+{-# INLINE swapL #-} --- | Reverse round trip through a connection.+-- | Reverse round trip through a 'ConnK' or 'ConnL'. ----- > x >= counitL c x+-- This is the counit of the resulting comonad: ----- >>> counitL (conn @_ @() @Ordering) LT+-- > x >~ counit c x+--+-- >>> counit (conn @_ @() @Ordering) LT -- LT--- >>> counitL (conn @_ @() @Ordering) GT+-- >>> counit (conn @_ @() @Ordering) GT -- LT+counit :: ConnL a b -> b -> b+counit c = ceilingWith1 c id+{-# INLINE counit #-}++-- | Round trip through a 'ConnK' or 'ConnL'. ---counitL :: ConnL a b -> b -> b-counitL c = lowerL1 c id+-- > upper c = upper1 c id = embed c . ceilingWith c+-- > x <= upper c x+--+-- >>> compare pi $ upper f64f32 pi+-- LT+upper :: ConnL a b -> a -> a+upper c = upper1 c id+{-# INLINE upper #-} --- | Extract the lower half of a 'Trip' or 'ConnL'.+-- | Map over a 'ConnK' or 'ConnL' from the right.+upper1 :: ConnL a b -> (b -> b) -> a -> a+upper1 (ConnL f g) h a = g $ h (f a)+{-# INLINE upper1 #-}++-- | Zip over a 'ConnK' or 'ConnL' from the right.+upper2 :: ConnL a b -> (b -> b -> b) -> a -> a -> a+upper2 (ConnL f g) h a1 a2 = g $ h (f a1) (f a2)+{-# INLINE upper2 #-}++-- | Obtain the principal filter in /B/ generated by an element of /A/. ----- When /a/ and /b/ are lattices we have:+-- A subset /B/ of a lattice is an filter if and only if it is an upper set+-- that is closed under finite meets, i.e., it is nonempty and for all+-- /x/, /y/ in /B/, the element @x `meet` y@ is also in /b/. ----- > lowerL c (x1 \/ a2) = lowerL c x1 \/ lowerL c x2+-- /filterWith/ and /idealWith/ commute with /Down/: ----- This is the adjoint functor theorem for preorders.+-- > filterWith c a b <=> idealWith c (Down a) (Down b) ----- >>> upperR f64f32 pi--- 3.1415925--- >>> lowerL f64f32 pi--- 3.1415927+-- > filterWith c (Down a) (Down b) <=> idealWith c a b ---lowerL :: ConnL a b -> a -> b-lowerL (ConnL f _) = f---- | Map over a connection from the left.+-- /filterWith c a/ is upward-closed for all /a/: ---lowerL1 :: ConnL a b -> (a -> a) -> b -> b-lowerL1 (ConnL f g) h b = f $ h (g b)---- | Zip over a connection from the left.+-- > a <= b1 && b1 <= b2 => a <= b2 ---lowerL2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b-lowerL2 (ConnL f g) h b1 b2 = f $ h (g b1) (g b2)---- | Map over a connection from the left.+-- > a1 <= b && inf a2 <= b => ceiling a1 `meet` ceiling a2 <= b ---upperL1 :: ConnL a b -> (b -> b) -> a -> a-upperL1 (ConnL f g) h a = g $ h (f a)+-- See <https://en.wikipedia.org/wiki/Filter_(mathematics)>+filterWith :: Preorder b => ConnL a b -> a -> b -> Bool+filterWith c a b = ceilingWith c a <~ b+{-# INLINE filterWith #-} --- | Zip over a connection from the left.+-- | Extract the left half of a 'ConnK' or 'ConnL'. ---upperL2 :: ConnL a b -> (b -> b -> b) -> a -> a -> a-upperL2 (ConnL f g) h a1 a2 = g $ h (f a1) (f a2)+-- >>> floorWith f64f32 pi+-- 3.1415925+-- >>> ceilingWith f64f32 pi+-- 3.1415927+ceilingWith :: ConnL a b -> a -> b+ceilingWith (ConnL f _) = f+{-# INLINE ceilingWith #-} +-- | Map over a 'ConnK' or 'ConnL' from the left.+ceilingWith1 :: ConnL a b -> (a -> a) -> b -> b+ceilingWith1 (ConnL f g) h b = f $ h (g b)+{-# INLINE ceilingWith1 #-}++-- | Zip over a 'ConnK' or 'ConnL' from the left.+ceilingWith2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b+ceilingWith2 (ConnL f g) h b1 b2 = f $ h (g b1) (g b2)+{-# INLINE ceilingWith2 #-}+ --------------------------------------------------------------------- -- ConnR ---------------------------------------------------------------------@@ -252,126 +389,144 @@ -- use one version over the other. -- -- However some use cases (e.g. rounding) require an adjoint triple--- of connections (i.e. a 'Trip') that can lower into a standard+-- of connections (i.e. a 'ConnK') that can lower into a standard -- connection in either of two ways.--- type ConnR = Conn 'R  -- | A view pattern for a 'ConnR'. -- -- /Caution/: /ConnR f g/ must obey \(f \dashv g \). This condition is not checked.--- pattern ConnR :: (b -> a) -> (a -> b) -> ConnR a b-pattern ConnR f g <- (embed &&& _1 -> (f, g)) where ConnR f g = Conn_ (g &&& g) f+pattern ConnR f g <- (embed &&& _1 -> (f, g)) where ConnR f g = Galois (g &&& g) f+ {-# COMPLETE ConnR #-} --- | Convert an arbitrary 'Conn' to an inverted 'ConnR'.+-- | Convert an inverted 'ConnR' to a 'ConnR'. ----- >>> counitR (downR $ conn @_ @() @Ordering) (Down LT)+-- > upR . downR = downR . upR = id+upR :: ConnR (Down a) (Down b) -> ConnR b a+upR (ConnR f g) = ConnR g' f'+  where+    f' x = let (Down y) = f (Down x) in y+    g' x = let (Down y) = g (Down x) in y+{-# INLINE upR #-}++-- | Convert a 'ConnR' to an inverted 'ConnR'.+--+-- >>> lower (downR $ conn @_ @() @Ordering) (Down LT) -- Down GT--- >>> counitR (downR $ conn @_ @() @Ordering) (Down GT)+-- >>> lower (downR $ conn @_ @() @Ordering) (Down GT) -- Down GT--- downR :: ConnR a b -> ConnR (Down b) (Down a) downR (ConnR f g) = ConnR (\(Down x) -> Down $ g x) (\(Down x) -> Down $ f x)+{-# INLINE downR #-}  -- | Witness to the symmetry between 'ConnL' and 'ConnR'. -- -- > swapL . swapR = id -- > swapR . swapL = id--- swapR :: ConnL a b -> ConnR b a swapR (ConnL f g) = ConnR f g+{-# INLINE swapR #-} --- | Round trip through a connection.+-- | Round trip through a 'ConnK' or 'ConnR'. ----- > unitR c = upperR1 c id = upperR c . embed c--- > x <= unitR c x+-- This is the unit of the resulting monad: ----- >>> unitR (conn @_ @() @Ordering) LT+-- > x <~ unit c x+-- > unit c = floorWith1 c id = floorWith c . embed c+--+-- >>> unit (conn @_ @() @Ordering) LT -- GT--- >>> unitR (conn @_ @() @Ordering) GT+-- >>> unit (conn @_ @() @Ordering) GT -- GT----unitR :: ConnR a b -> b -> b-unitR c = upperR1 c id+unit :: ConnR a b -> b -> b+unit c = floorWith1 c id+{-# INLINE unit #-} --- | Reverse round trip through a connection.+-- | Reverse round trip through a 'ConnK' or 'ConnR'. ----- > x >= counitR c x+-- > x >~ lower c x ----- >>> compare pi $ counitR f64f32 pi+-- >>> compare pi $ lower f64f32 pi -- GT----counitR :: ConnR a b -> a -> a-counitR c = lowerR1 c id+lower :: ConnR a b -> a -> a+lower c = lower1 c id+{-# INLINE lower #-} --- | Extract the upper half of a connection.+-- | Map over a 'ConnK' or 'ConnR' from the left.+lower1 :: ConnR a b -> (b -> b) -> a -> a+lower1 (ConnR f g) h a = f $ h (g a)+{-# INLINE lower1 #-}++-- | Zip over a 'ConnK' or 'ConnR' from the left.+lower2 :: ConnR a b -> (b -> b -> b) -> a -> a -> a+lower2 (ConnR f g) h a1 a2 = f $ h (g a1) (g a2)+{-# INLINE lower2 #-}++-- | Obtain the principal ideal in /B/ generated by an element of /A/. ----- When /a/ and /b/ are lattices we have:+-- A subset /B/ of a lattice is an ideal if and only if it is a lower set+-- that is closed under finite joins, i.e., it is nonempty and for all+-- /x/, /y/ in /B/, the element /x `join` y/ is also in /B/. ----- > upperR c (x1 /\ x2) = upperR c x1 /\ upperR c x2+-- /idealWith c a/ is downward-closed for all /a/: ----- This is the adjoint functor theorem for preorders.+-- > a >= b1 && b1 >= b2 => a >= b2 ----- >>> upperR f64f32 pi--- 3.1415925--- >>> lowerL f64f32 pi--- 3.1415927+-- > a1 >= b && a2 >= b => floor a1 `join` floor a2 >= b ---upperR :: ConnR a b -> a -> b-upperR (ConnR _ g) = g+-- See <https://en.wikipedia.org/wiki/Ideal_(order_theory)>+idealWith :: Preorder b => ConnR a b -> a -> b -> Bool+idealWith c a b = b <~ floorWith c a+{-# INLINE idealWith #-} --- | Map over a connection from the left.+-- | Extract the right half of a 'ConnK' or 'ConnR' ---upperR1 :: ConnR a b -> (a -> a) -> b -> b-upperR1 (ConnR f g) h b = g $ h (f b)---- | Zip over a connection from the left.+-- This is the adjoint functor theorem for preorders. ---upperR2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b-upperR2 (ConnR f g) h b1 b2 = g $ h (f b1) (f b2)+-- >>> floorWith f64f32 pi+-- 3.1415925+-- >>> ceilingWith f64f32 pi+-- 3.1415927+floorWith :: ConnR a b -> a -> b+floorWith (ConnR _ g) = g+{-# INLINE floorWith #-} --- | Map over a connection from the right.----lowerR1 :: ConnR a b -> (b -> b) -> a -> a-lowerR1 (ConnR f g) h a = f $ h (g a)+-- | Map over a 'ConnK' or 'ConnR' from the right.+floorWith1 :: ConnR a b -> (a -> a) -> b -> b+floorWith1 (ConnR f g) h b = g $ h (f b)+{-# INLINE floorWith1 #-} --- | Zip over a connection from the right.----lowerR2 :: ConnR a b -> (b -> b -> b) -> a -> a -> a-lowerR2 (ConnR f g) h a1 a2 = f $ h (g a1) (g a2)+-- | Zip over a 'ConnK' or 'ConnR' from the right.+floorWith2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b+floorWith2 (ConnR f g) h b1 b2 = g $ h (f b1) (f b2)+{-# INLINE floorWith2 #-}  ------------------------------------------------------------------------ Connections+-- Combinators ---------------------------------------------------------------------  -- | Lift two 'Conn's into a 'Conn' on the <https://en.wikibooks.org/wiki/Category_Theory/Categories_of_ordered_sets coproduct order> -- -- > (choice id) (ab >>> cd) = (choice id) ab >>> (choice id) cd -- > (flip choice id) (ab >>> cd) = (flip choice id) ab >>> (flip choice id) cd--- choice :: Conn k a b -> Conn k c d -> Conn k (Either a c) (Either b d)-choice (Conn ab ba ab') (Conn cd dc cd') = Conn f g h where-  f = either (Left . ab) (Right . cd)-  g = either (Left . ba) (Right . dc)-  h = either (Left . ab') (Right . cd')+choice (Conn ab ba ab') (Conn cd dc cd') = Conn f g h+  where+    f = either (Left . ab) (Right . cd)+    g = either (Left . ba) (Right . dc)+    h = either (Left . ab') (Right . cd')+{-# INLINE choice #-}  -- | Lift two 'Conn's into a 'Conn' on the <https://en.wikibooks.org/wiki/Order_Theory/Preordered_classes_and_poclasses#product_order product order> -- -- > (strong id) (ab >>> cd) = (strong id) ab >>> (strong id) cd -- > (flip strong id) (ab >>> cd) = (flip strong id) ab >>> (flip strong id) cd--- strong :: Conn k a b -> Conn k c d -> Conn k (a, c) (b, d)-strong (Conn ab ba ab') (Conn cd dc cd') = Conn f g h where-  f = bimap ab cd -  g = bimap ba dc-  h = bimap ab' cd'---- | Lift a 'Conn' into a functor.------ /Caution/: This function will result in an invalid connection--- if the functor alters the internal preorder (i.e. 'Data.Ord.Down').----fmapped :: Functor f => Conn k a b -> Conn k (f a) (f b)-fmapped (Conn f g h) = Conn (fmap f) (fmap g) (fmap h)+strong (Conn ab ba ab') (Conn cd dc cd') = Conn f g h+  where+    f = bimap ab cd+    g = bimap ba dc+    h = bimap ab' cd'+{-# INLINE strong #-}
− src/Data/Connection/Double.hs
@@ -1,322 +0,0 @@-{-# Language ConstraintKinds #-}-{-# Language Safe            #-}-{-# Language RankNTypes      #-}-module Data.Connection.Double (-    f64f32-  , f64i08-  , f64i16-  , f64i32-  , min64-  , max64-  , ulp-  , covers-  , shift-  , within-  , epsilon-  , until-) where-----import safe Data.Universe.Class-import safe Data.Bool-import safe Data.Connection.Conn-import safe Data.Int-import safe Data.Order-import safe Data.Order.Extended-import safe Data.Order.Syntax hiding (min, max)-import safe Data.Word-import safe GHC.Float as F-import safe Prelude hiding (Eq(..), Ord(..), until)-import safe qualified Data.Connection.Float as F32-import safe qualified Prelude as P-------------------------------------------------------------------------- Connections------------------------------------------------------------------------f64f32 :: Conn k Double Float-f64f32 = Conn f1 g f2 where-  f1 x = let est = F.double2Float x in-          if g est >~ x-          then est-          else ascend32 est g x--  f2 x = let est = F.double2Float x in-          if g est <~ x-          then est-          else descend32 est g x--  g = F.float2Double--  ascend32 z g1 y = until (\x -> g1 x >~ y) (<~) (F32.shift 1) z--  descend32 z h1 x = until (\y -> h1 y <~ x) (>~) (F32.shift (-1)) z---- | All 'Data.Int.Int08' values are exactly representable in a 'Double'.-f64i08 :: Conn k Double (Extended Int8)-f64i08 = triple 127---- | All 'Data.Int.Int16' values are exactly representable in a 'Double'.-f64i16 :: Conn k Double (Extended Int16)-f64i16 = triple 32767---- | All 'Data.Int.Int32' values are exactly representable in a 'Double'.-f64i32 :: Conn k Double (Extended Int32)-f64i32 = triple 2147483647--------------------------------------------------------------------------- Double-------------------------------------------------------------------------- | A /NaN/-handling min function.------ > min64 x NaN = x--- > min64 NaN y = y----min64 :: Double -> Double -> Double-min64 x y = case (isNaN x, isNaN y) of-  (False, False) -> if x <= y then x else y-  (False, True) -> x-  (True, False) -> y-  (True, True)  -> x---- | A /NaN/-handling max function.------ > max64 x NaN = x--- > max64 NaN y = y----max64 :: Double -> Double -> Double-max64 x y = case (isNaN x, isNaN y) of-  (False, False) -> if x >= y then x else y-  (False, True) -> x-  (True, False) -> y-  (True, True)  -> x---- | Covering relation on the /N5/ lattice of doubles.------ < https://en.wikipedia.org/wiki/Covering_relation >------ >>> covers 1 (shift 1 1)--- True--- >>> covers 1 (shift 2 1)--- False----covers :: Double -> Double -> Bool-covers x y = x ~~ shift (-1) y---- | Compute the signed distance between two doubles in units of least precision.------ >>> ulp 1.0 (shift 1 1.0)--- Just (LT,1)--- >>> ulp (0.0/0.0) 1.0--- Nothing----ulp :: Double -> Double -> Maybe (Ordering, Word64)-ulp x y = fmap f $ pcompare x y-  where  x' = doubleInt64 x-         y' = doubleInt64 y-         f LT = (LT, fromIntegral . abs $ y' - x')-         f EQ = (EQ, 0)-         f GT = (GT, fromIntegral . abs $ x' - y')---- | Shift by /n/ units of least precision.------ >>> shift 1 0--- 1.0e-45--- >>> shift 1 $ 0/0--- NaN--- >>> shift (-1) $ 0/0--- NaN--- >>> shift 1 $ 1/0--- Infinity----shift :: Int64 -> Double -> Double-shift n x | x ~~ 0/0 = x-          | otherwise = int64Double . clamp64 . (+ n) . doubleInt64 $ x---- | Compare two double-precision floats for approximate equality.------ Required accuracy is specified in units of least precision.------ See also <https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/>.--- -within :: Word64 -> Double -> Double -> Bool-within tol x y = maybe False ((<= tol) . snd) $ ulp x y---- | Difference between 1 and the smallest representable value greater than 1.------ > epsilon = shift 1 1 - 1------ >>> epsilon--- 2.220446049250313e-16----epsilon :: Double-epsilon = shift 1 1.0 - 1.0--{----- | Minimal positive value.------ >>> minimal64--- 5.0e-324--- >>> shift (-1) minimal64--- 0----minimal64 :: Double-minimal64 = shift 1 0.0---- | Maximum finite value.------ >>> maximal64--- 1.7976931348623157e308--- >>> shift 1 maximal64--- Infinity--- >>> shift (-1) $ negate maximal64--- -Infinity--- -maximal64 :: Double-maximal64 = shift (-1) maxBound --}------------------------------------------------------------------------------------ Orphans-----------------------------------------------------------------------{--instance Universe Double where-  universe = 0/0 : indexFromTo (minBound ... maxBound)--instance Finite Double--}------------------------------------------------------------------------- Internal------------------------------------------------------------------------{-# INLINE until #-}-until :: (a -> Bool) -> (a -> a -> Bool) -> (a -> a) -> a -> a-until pre rel f seed = go seed-  where go x | x' `rel` x = x-             | pre x = x-             | otherwise = go x'-          where x' = f x------- Non-monotonic function -signed64 :: Word64 -> Int64-signed64 x | x < 0x8000000000000000 = fromIntegral x-           | otherwise      = fromIntegral (maxBound P.- (x P.- 0x8000000000000000))---- Non-monotonic function converting from 2s-complement format.-unsigned64 :: Int64 -> Word64-unsigned64 x | x >~ 0  = fromIntegral x-             | otherwise = 0x8000000000000000 + (maxBound P.- (fromIntegral x))---- Clamp between the int representations of -1/0 and 1/0 -clamp64 :: Int64 -> Int64-clamp64 = P.max (-9218868437227405313) . P.min 9218868437227405312 --int64Double :: Int64 -> Double-int64Double = word64Double . unsigned64--doubleInt64 :: Double -> Int64-doubleInt64 = signed64 . doubleWord64 ---- Bit-for-bit conversion.-word64Double :: Word64 -> Double-word64Double = F.castWord64ToDouble---- TODO force to pos representation?--- Bit-for-bit conversion.-doubleWord64 :: Double -> Word64-doubleWord64 = (+0) . F.castDoubleToWord64--{----- | Exact embedding up to the largest representable 'Int64'.-f64i64 :: Conn Double (Maybe Int64)-f64i64 = Conn (nanf f) (nan g) where-  f x | abs x <~ 2**53-1 = P.ceiling x-      | otherwise = if x >~ 0 then 2^53 else minBound--  g i | abs' i <~ 2^53-1 = fromIntegral i-      | otherwise = if i >~ 0 then 1/0 else -2**53-  --- | Exact embedding up to the largest representable 'Int64'.-i64f64 :: Conn (Maybe Int64) Double-i64f64 = Conn (nan g) (nanf f) where-  f x | abs x <~ 2**53-1 = P.floor x-      | otherwise = if x >~ 0 then maxBound else -2^53--  g i | abs i <~ 2^53-1 = fromIntegral i-      | otherwise = if i >~ 0 then 2**53 else -1/0---- | Exact embedding up to the largest representable 'Int64'.-f64ixx :: Conn Double (Maybe Int)-f64ixx = Conn (nanf f) (nan g) where-  f x | abs x <~ 2**53-1 = P.ceiling x-      | otherwise = if x >~ 0 then 2^53 else minBound--  g i | abs' i <~ 2^53-1 = fromIntegral i-      | otherwise = if i >~ 0 then 1/0 else -2**53-  --- | Exact embedding up to the largest representable 'Int64'.-ixxf64 :: Conn (Maybe Int) Double-ixxf64 = Conn (nan g) (nanf f) where-  f x | abs x <~ 2**53-1 = P.floor x-      | otherwise = if x >~ 0 then maxBound else -2^53--  g i | abs i <~ 2^53-1 = fromIntegral i-      | otherwise = if i >~ 0 then 2**53 else -1/0---}---{---- |------ @'lower64' x@ is the least element /y/ in the descending--- chain such that @not $ f y '<~' x@.----lower :: Preorder a => Double -> (Double -> a) -> a -> Double-lower z f x = until (\y -> f y <~ x) (>~) (shift $ -1) z---- |------ @'upper64' y@ is the greatest element /x/ in the ascending--- chain such that @g x '<~' y@.----upper :: Preorder a => Double -> (Double -> a) -> a -> Double-upper z g y = until (\x -> g x >~ y) (<~) (shift 1) z---- |------ @'lower' x@ is the least element /y/ in the descending--- chain such that @not $ f y '<~' x@.----lower :: Preorder a => Float -> (Float -> a) -> a -> Float-lower z f x = until (\y -> f y <~ x) (>~) (F32.shift $ -1) z---- |------ @'upper' y@ is the greatest element /x/ in the ascending--- chain such that @not $ g x '>~' y@.----upper :: Preorder a => Float -> (Float -> a) -> a -> Float-upper z g y = until (\x -> g x >~ y) (<~) (F32.shift 1) z--}--------------------------------------------------------------------------- Internal------------------------------------------------------------------------triple :: (Bounded a, Integral a) => Double -> Conn k Double (Extended a)-triple high = Conn f1 g f2 where-  f1 = liftExtended (~~ -1/0) (\x -> x ~~ 0/0 || x > high) $ \x -> if x < low then minBound else P.ceiling x--  f2 = liftExtended (\x -> x ~~ 0/0 || x < low) (~~ 1/0) $ \x -> if x > high then maxBound else P.floor x--  g = extended (-1/0) (1/0) P.fromIntegral- -  low = -1 - high
src/Data/Connection/Float.hs view
@@ -1,17 +1,30 @@-{-# Language ConstraintKinds #-}-{-# Language Safe            #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE Safe #-}+ module Data.Connection.Float (-  -- * Connections-    f32i08-  , f32i16-  --, f32i32-  , min32-  , max32-  , covers-  , ulp-  , shift-  , within-  , epsilon+    -- * Connections+    f32i08,+    f32i16,+    f64i08,+    f64i16,+    f64i32,+    f64f32,++    -- * Float+    min32,+    max32,+    ulp32,+    near32,+    shift32,++    -- * Double+    min64,+    max64,+    ulp64,+    near64,+    shift64,+    until, ) where  import safe Data.Bool@@ -19,13 +32,63 @@ import safe Data.Int import safe Data.Order import safe Data.Order.Extended-import safe Data.Order.Syntax+import safe Data.Order.Syntax hiding (max, min) import safe Data.Word import safe GHC.Float as F-import safe Prelude hiding (Eq(..), Ord(..), until)-import safe qualified Prelude as P +import safe Prelude hiding (Eq (..), Ord (..), until)+import safe qualified Prelude as P  ---------------------------------------------------------------------+-- Connections+---------------------------------------------------------------------++-- | All 'Data.Int.Int08' values are exactly representable in a 'Float'.+f32i08 :: Conn k Float (Extended Int8)+f32i08 = triple 127++-- | All 'Data.Int.Int16' values are exactly representable in a 'Float'.+--+--  > ceilingWith f32i16 32767.0+--  Extended 32767+--  > ceilingWith f32i16 32767.1+--  Top+f32i16 :: Conn k Float (Extended Int16)+f32i16 = triple 32767++-- | All 'Data.Int.Int08' values are exactly representable in a 'Double'.+f64i08 :: Conn k Double (Extended Int8)+f64i08 = triple 127++-- | All 'Data.Int.Int16' values are exactly representable in a 'Double'.+f64i16 :: Conn k Double (Extended Int16)+f64i16 = triple 32767++-- | All 'Data.Int.Int32' values are exactly representable in a 'Double'.+f64i32 :: Conn k Double (Extended Int32)+f64i32 = triple 2147483647++f64f32 :: Conn k Double Float+f64f32 = Conn f1 g f2+  where+    f1 x =+        let est = F.double2Float x+         in if g est >~ x+                then est+                else ascend32 est g x++    f2 x =+        let est = F.double2Float x+         in if g est <~ x+                then est+                else descend32 est g x++    g = F.float2Double++    ascend32 z g1 y = until (\x -> g1 x >~ y) (<~) (shift32 1) z++    descend32 z h1 x = until (\y -> h1 y <~ x) (>~) (shift32 (-1)) z++--------------------------------------------------------------------- -- Float --------------------------------------------------------------------- @@ -33,124 +96,200 @@ -- -- > min32 x NaN = x -- > min32 NaN y = y--- min32 :: Float -> Float -> Float min32 x y = case (isNaN x, isNaN y) of-  (False, False) -> if x <= y then x else y-  (False, True) -> x-  (True, False) -> y-  (True, True)  -> x+    (False, False) -> if x <= y then x else y+    (False, True) -> x+    (True, False) -> y+    (True, True) -> x  -- | A /NaN/-handling max32 function. -- -- > max32 x NaN = x -- > max32 NaN y = y--- max32 :: Float -> Float -> Float max32 x y = case (isNaN x, isNaN y) of-  (False, False) -> if x >= y then x else y-  (False, True) -> x-  (True, False) -> y-  (True, True)  -> x---- | Covering relation on the /N5/ lattice of floats.------ < https://en.wikipedia.org/wiki/Covering_relation >------ >>> covers 1 (shift 1 1)--- True--- >>> covers 1 (shift 2 1)--- False----covers :: Float -> Float -> Bool-covers x y = x ~~ shift (-1) y+    (False, False) -> if x >= y then x else y+    (False, True) -> x+    (True, False) -> y+    (True, True) -> x  -- | Compute the signed distance between two floats in units of least precision. ----- >>> ulp 1.0 (shift 1 1.0)+-- >>> ulp32 1.0 (shift32 1 1.0) -- Just (LT,1)--- >>> ulp (0.0/0.0) 1.0+-- >>> ulp32 (0.0/0.0) 1.0 -- Nothing+ulp32 :: Float -> Float -> Maybe (Ordering, Word32)+ulp32 x y = fmap f $ pcompare x y+  where+    x' = floatInt32 x+    y' = floatInt32 y+    f LT = (LT, fromIntegral . abs $ y' - x')+    f EQ = (EQ, 0)+    f GT = (GT, fromIntegral . abs $ x' - y')++-- | Compare two floats for approximate equality. ---ulp :: Float -> Float -> Maybe (Ordering, Word32)-ulp x y = fmap f $ pcompare x y-  where  x' = floatInt32 x-         y' = floatInt32 y-         f LT = (LT, fromIntegral . abs $ y' - x')-         f EQ = (EQ, 0)-         f GT = (GT, fromIntegral . abs $ x' - y')+-- Required accuracy is specified in units of least precision.+--+-- See also <https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/>.+near32 :: Word32 -> Float -> Float -> Bool+near32 tol x y = maybe False ((<= tol) . snd) $ ulp32 x y  -- | Shift a float by /n/ units of least precision. ----- >>> shift 1 0+-- >>> shift32 1 0 -- 1.0e-45--- >>> shift 1 $ 0/0+-- >>> shift32 1 1 - 1+-- 1.1920929e-7+-- >>> shift32 1 $ 0/0 -- NaN--- >>> shift (-1) $ 0/0+-- >>> shift32 (-1) $ 0/0 -- NaN--- >>> shift 1 $ 1/0+-- >>> shift32 1 $ 1/0 -- Infinity----shift :: Int32 -> Float -> Float-shift n x | x ~~ 0/0 = x-          | otherwise = int32Float . clamp32 . (+ n) . floatInt32 $ x+shift32 :: Int32 -> Float -> Float+shift32 n x+    | x ~~ 0 / 0 = x+    | otherwise = int32Float . clamp32 . (+ n) . floatInt32 $ x --- | Compare two floats for approximate equality.------ Required accuracy is specified in units of least precision.------ See also <https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/>.--- -within :: Word32 -> Float -> Float -> Bool-within tol x y = maybe False ((<= tol) . snd) $ ulp x y+---------------------------------------------------------------------+-- Double+--------------------------------------------------------------------- --- | Difference between 1 and the smallest representable value greater than 1.+-- | A /NaN/-handling min function. ----- > epsilon = shift 1 1 - 1+-- > min64 x NaN = x+-- > min64 NaN y = y+min64 :: Double -> Double -> Double+min64 x y = case (isNaN x, isNaN y) of+    (False, False) -> if x <= y then x else y+    (False, True) -> x+    (True, False) -> y+    (True, True) -> x++-- | A /NaN/-handling max function. ----- >>> epsilon--- 1.1920929e-7+-- > max64 x NaN = x+-- > max64 NaN y = y+max64 :: Double -> Double -> Double+max64 x y = case (isNaN x, isNaN y) of+    (False, False) -> if x >= y then x else y+    (False, True) -> x+    (True, False) -> y+    (True, True) -> x++-- | Compute the signed distance between two doubles in units of least precision. ---epsilon :: Float-epsilon = shift 1 1.0 - 1.0+-- >>> ulp64 1.0 (shift64 1 1.0)+-- Just (LT,1)+-- >>> ulp64 (0.0/0.0) 1.0+-- Nothing+ulp64 :: Double -> Double -> Maybe (Ordering, Word64)+ulp64 x y = fmap f $ pcompare x y+  where+    x' = doubleInt64 x+    y' = doubleInt64 y+    f LT = (LT, fromIntegral . abs $ y' - x')+    f EQ = (EQ, 0)+    f GT = (GT, fromIntegral . abs $ x' - y') -{---- | Minimal32 positive value.+-- | Compare two double-precision floats for approximate equality. ----- >>> minimal32--- 1.0e-45--- >>> shift (-1) minimal32--- 0+-- Required accuracy is specified in units of least precision. ---minimal32 :: Float-minimal32 = shift 1 0.0+-- See also <https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/>.+near64 :: Word64 -> Double -> Double -> Bool+near64 tol x y = maybe False ((<= tol) . snd) $ ulp64 x y --- | Maximum finite value.+-- | Shift by /n/ units of least precision. ----- >>> maximal32--- 3.4028235e38--- >>> shift 1 maximal32+-- >>> shift64 1 0+-- 5.0e-324+-- >>> shift64 1 1 - 1+-- 2.220446049250313e-16+-- >>> shift64 1 $ 0/0+-- NaN+-- >>> shift64 (-1) $ 0/0+-- NaN+-- >>> shift64 1 $ 1/0 -- Infinity--- >>> shift (-1) $ negate maximal32--- -Infinity----maximal32 :: Float-maximal32 = shift (-1) (1/0) ---}+shift64 :: Int64 -> Double -> Double+shift64 n x+    | x ~~ 0 / 0 = x+    | otherwise = int64Double . clamp64 . (+ n) . doubleInt64 $ x  ------------------------------------------------------------------------ Float+-- Internal --------------------------------------------------------------------- --- | All 'Data.Int.Int08' values are exactly representable in a 'Float'.-f32i08 :: Conn k Float (Extended Int8)-f32i08 = signedTriple 127+{-# INLINE until #-}+until :: (a -> Bool) -> (a -> a -> Bool) -> (a -> a) -> a -> a+until pre rel f seed = go seed+  where+    go x+        | x' `rel` x = x+        | pre x = x+        | otherwise = go x'+      where+        x' = f x --- | All 'Data.Int.Int16' values are exactly representable in a 'Float'.-f32i16 :: Conn k Float (Extended Int16)-f32i16 = signedTriple 32767+-- Non-monotonic function+signed32 :: Word32 -> Int32+signed32 x+    | x < 0x80000000 = fromIntegral x+    | otherwise = fromIntegral (maxBound - (x - 0x80000000)) +-- Non-monotonic function+signed64 :: Word64 -> Int64+signed64 x+    | x < 0x8000000000000000 = fromIntegral x+    | otherwise = fromIntegral (maxBound P.- (x P.- 0x8000000000000000))++-- Non-monotonic function converting from 2s-complement format.+unsigned32 :: Int32 -> Word32+unsigned32 x+    | x >= 0 = fromIntegral x+    | otherwise = 0x80000000 + (maxBound - (fromIntegral x))++-- Non-monotonic function converting from 2s-complement format.+unsigned64 :: Int64 -> Word64+unsigned64 x+    | x >~ 0 = fromIntegral x+    | otherwise = 0x8000000000000000 + (maxBound P.- (fromIntegral x))++int32Float :: Int32 -> Float+int32Float = F.castWord32ToFloat . unsigned32++floatInt32 :: Float -> Int32+floatInt32 = signed32 . (+ 0) . F.castFloatToWord32++int64Double :: Int64 -> Double+int64Double = F.castWord64ToDouble . unsigned64++doubleInt64 :: Double -> Int64+doubleInt64 = signed64 . (+ 0) . F.castDoubleToWord64++-- Clamp between the int representations of -1/0 and 1/0+clamp32 :: Int32 -> Int32+clamp32 = P.max (-2139095041) . P.min 2139095040++-- Clamp between the int representations of -1/0 and 1/0+clamp64 :: Int64 -> Int64+clamp64 = P.max (-9218868437227405313) . P.min 9218868437227405312++triple :: (RealFrac a, Preorder a, Bounded b, Integral b) => a -> Conn k a (Extended b)+triple high = Conn f g h+  where+    f = liftExtended (~~ -1 / 0) (\x -> x ~~ 0 / 0 || x > high) $ \x -> if x < low then minBound else P.ceiling x++    g = extended (-1 / 0) (1 / 0) P.fromIntegral++    h = liftExtended (\x -> x ~~ 0 / 0 || x < low) (~~ 1 / 0) $ \x -> if x > high then maxBound else P.floor x++    low = -1 - high+ {- -- | Exact embedding up to the largest representable 'Int32'. f32i32 :: ConnL Float (Maybe Int32)@@ -161,7 +300,6 @@   g i | abs' i <~ 2^24-1 = fromIntegral i       | otherwise = if i >~ 0 then 1/0 else -2**24 - -- | Exact embedding up to the largest representable 'Int32'. i32f32 :: ConnL (Maybe Int32) Float i32f32 = Conn (nan g) (nanf f) where@@ -170,47 +308,22 @@    g i | abs i <~ 2^24-1 = fromIntegral i       | otherwise = if i >~ 0 then 2**24 else -1/0--} ------------------------------------------------------------------------- Internal------------------------------------------------------------------------signedTriple :: (Bounded a, Integral a) => Float -> Conn k Float (Extended a)-signedTriple high = Conn f g h where--  f = liftExtended (~~ -1/0) (\x -> x ~~ 0/0 || x > high) $ \x -> if x < low then minBound else P.ceiling x--  g = extended (-1/0) (1/0) P.fromIntegral- -  h = liftExtended (\x -> x ~~ 0/0 || x < low) (~~ 1/0) $ \x -> if x > high then maxBound else P.floor x--  low = -1 - high---- Non-monotonic function -signed32 :: Word32 -> Int32-signed32 x | x < 0x80000000 = fromIntegral x-           | otherwise      = fromIntegral (maxBound - (x - 0x80000000))---- Non-monotonic function converting from 2s-complement format.-unsigned32 :: Int32 -> Word32-unsigned32 x | x >= 0  = fromIntegral x-             | otherwise = 0x80000000 + (maxBound - (fromIntegral x))---- Clamp between the int representations of -1/0 and 1/0 -clamp32 :: Int32 -> Int32-clamp32 = P.max (-2139095041) . P.min 2139095040--int32Float :: Int32 -> Float-int32Float = word32Float . unsigned32+-- | Exact embedding up to the largest representable 'Int64'.+f64i64 :: Conn Double (Maybe Int64)+f64i64 = Conn (nanf f) (nan g) where+  f x | abs x <~ 2**53-1 = P.ceiling x+      | otherwise = if x >~ 0 then 2^53 else minBound -floatInt32 :: Float -> Int32-floatInt32 = signed32 . floatWord32 +  g i | abs' i <~ 2^53-1 = fromIntegral i+      | otherwise = if i >~ 0 then 1/0 else -2**53 --- Bit-for-bit conversion.-word32Float :: Word32 -> Float-word32Float = F.castWord32ToFloat+-- | Exact embedding up to the largest representable 'Int64'.+f64ixx :: Conn Double (Maybe Int)+f64ixx = Conn (nanf f) (nan g) where+  f x | abs x <~ 2**53-1 = P.ceiling x+      | otherwise = if x >~ 0 then 2^53 else minBound --- Bit-for-bit conversion.-floatWord32 :: Float -> Word32-floatWord32 = (+0) .  F.castFloatToWord32+  g i | abs' i <~ 2^53-1 = fromIntegral i+      | otherwise = if i >~ 0 then 1/0 else -2**53+-}
src/Data/Connection/Int.hs view
@@ -1,164 +1,163 @@-{-# Language ConstraintKinds #-}-{-# Language Safe            #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+ module Data.Connection.Int (-  -- * Int8-    i08c08-  , i08w08-  , i08i16-  , i08i32-  , i08i64-  , i08int-  -- * Int16-  , i16c16-  , i16w16-  , i16i32-  , i16i64-  , i16int-  -- * Int32-  , i32c32-  , i32w32-  , i32i64-  , i32int-  -- * Int64-  , i64c64-  , i64w64-  , i64int-  -- * Int-  , ixxwxx-  , ixxi64-  , ixxint-  -- * Integer-  , intnat-  , natint-  ) where+    -- * Int16+    w08i16,+    i08i16, -import safe Control.Category ((>>>))+    -- * Int32+    w08i32,+    w16i32,+    i08i32,+    i16i32,++    -- * Int64+    w08i64,+    w16i64,+    w32i64,+    i08i64,+    i16i64,+    i32i64,++    -- * Int+    w08ixx,+    w16ixx,+    w32ixx,+    i08ixx,+    i16ixx,+    i32ixx,+    i64ixx,++    -- * Integer+    w08int,+    w16int,+    w32int,+    w64int,+    wxxint,+    natint,+    i08int,+    i16int,+    i32int,+    i64int,+    ixxint,+) where+ import safe Control.Applicative import safe Control.Monad import safe Data.Connection.Conn-import safe Data.Connection.Word import safe Data.Int-import safe Data.Order.Syntax import safe Data.Word-import safe Foreign.C.Types import safe Numeric.Natural-import safe Prelude hiding (Eq(..), Ord(..), Bounded)-import safe qualified Prelude as P--i08c08 :: ConnL Int8 CChar-i08c08 = ConnL CChar $ \(CChar x) -> x--i08w08 :: Conn k Int8 Word8-i08w08 = unsigned--i08int :: ConnL Int8 (Maybe Integer)-i08int = signed--i16c16 :: ConnL Int16 CShort-i16c16 = ConnL CShort $ \(CShort x) -> x--i16w16 :: Conn k Int16 Word16-i16w16 = unsigned+import safe Prelude -i16int :: ConnL Int16 (Maybe Integer)-i16int = signed+-- Int16+w08i16 :: ConnL Word8 (Maybe Int16)+w08i16 = signed -i32c32 :: ConnL Int32 CInt-i32c32 = ConnL CInt $ \(CInt x) -> x+i08i16 :: ConnL Int8 (Maybe Int16)+i08i16 = signed -i32w32 :: Conn k Int32 Word32-i32w32 = unsigned+-- Int32+w08i32 :: ConnL Word8 (Maybe Int32)+w08i32 = signed -i32int :: ConnL Int32 (Maybe Integer)-i32int = signed+w16i32 :: ConnL Word16 (Maybe Int32)+w16i32 = signed -i64c64 :: ConnL Int64 CLong-i64c64 = ConnL CLong $ \(CLong x) -> x+i08i32 :: ConnL Int8 (Maybe Int32)+i08i32 = signed -i64w64 :: Conn k Int64 Word64-i64w64 = unsigned+i16i32 :: ConnL Int16 (Maybe Int32)+i16i32 = signed --- | /Caution/: This assumes that 'Int' on your system is 64 bits.-ixxi64 :: Conn k Int Int64-ixxi64 = Conn fromIntegral fromIntegral fromIntegral+-- Int64+w08i64 :: ConnL Word8 (Maybe Int64)+w08i64 = signed -i64int :: ConnL Int64 (Maybe Integer)-i64int = signed+w16i64 :: ConnL Word16 (Maybe Int64)+w16i64 = signed -ixxwxx :: Conn k Int Word-ixxwxx = unsigned+w32i64 :: ConnL Word32 (Maybe Int64)+w32i64 = signed --- | /Caution/: This assumes that 'Int' on your system is 64 bits.-ixxint :: ConnL Int (Maybe Integer)-ixxint = signed+i08i64 :: ConnL Int8 (Maybe Int64)+i08i64 = signed -intnat :: ConnL Integer Natural-intnat = ConnL (fromIntegral . max 0) fromIntegral+i16i64 :: ConnL Int16 (Maybe Int64)+i16i64 = signed -natint :: ConnL Natural (Maybe Integer)-natint = ConnL (fmap fromIntegral . fromPred (==0)) (maybe 0 $ P.fromInteger . max 0)+i32i64 :: ConnL Int32 (Maybe Int64)+i32i64 = signed -i08i16 :: ConnL Int8 Int16-i08i16 = i08w08 >>> w08w16 >>> w16i16+-- Int+w08ixx :: ConnL Word8 (Maybe Int)+w08ixx = signed -i08i32 :: ConnL Int8 Int32-i08i32 = i08w08 >>> w08w32 >>> w32i32+w16ixx :: ConnL Word16 (Maybe Int)+w16ixx = signed -i08i64 :: ConnL Int8 Int64-i08i64 = i08w08 >>> w08w64 >>> w64i64+w32ixx :: ConnL Word32 (Maybe Int)+w32ixx = signed -i16i32 :: ConnL Int16 Int32-i16i32 = i16w16 >>> w16w32 >>> w32i32+i08ixx :: ConnL Int8 (Maybe Int)+i08ixx = signed -i16i64 :: ConnL Int16 Int64-i16i64 = i16w16 >>> w16w64 >>> w64i64+i16ixx :: ConnL Int16 (Maybe Int)+i16ixx = signed -i32i64 :: ConnL Int32 Int64-i32i64 = i32w32 >>> w32w64 >>> w64i64+i32ixx :: ConnL Int32 (Maybe Int)+i32ixx = signed ------------------------------------------------------------------------- Internal----------------------------------------------------------------------+-- | /Caution/: This assumes that 'Int' on your system is 64 bits.+i64ixx :: Conn k Int64 Int+i64ixx = Conn fromIntegral fromIntegral fromIntegral +-- Integer+w08int :: ConnL Word8 (Maybe Integer)+w08int = signed -fromPred :: Alternative f => (t -> Bool) -> t -> f t-fromPred p a = a <$ guard (p a)+w16int :: ConnL Word16 (Maybe Integer)+w16int = signed -unsigned :: (P.Bounded a, Integral a, Integral b) => Conn k a b-unsigned = Conn f g f where-  f y = fromIntegral (y + P.maxBound + 1)-  g x = fromIntegral x - P.minBound+w32int :: ConnL Word32 (Maybe Integer)+w32int = signed -signed :: forall a. (P.Bounded a, Integral a) => ConnL a (Maybe Integer)-signed = ConnL f g where-  f = fmap fromIntegral . fromPred (==P.minBound)-  g = maybe P.minBound $ P.fromInteger . min (fromIntegral @a P.maxBound) . max (fromIntegral @a P.minBound)+w64int :: ConnL Word64 (Maybe Integer)+w64int = signed -{-+wxxint :: ConnL Word (Maybe Integer)+wxxint = signed +natint :: ConnL Natural (Maybe Integer)+natint = ConnL (fmap fromIntegral . fromPred (/= 0)) (maybe 0 $ fromInteger . max 0) -clip08 :: Integer -> Integer-clip08 = min 127 . max (-128)+i08int :: ConnL Int8 (Maybe Integer)+i08int = signed -clip16 :: Integer -> Integer-clip16 = min 32767 . max (-32768)+i16int :: ConnL Int16 (Maybe Integer)+i16int = signed -clip32 :: Integer -> Integer-clip32 = min 2147483647 . max (-2147483648)+i32int :: ConnL Int32 (Maybe Integer)+i32int = signed -clip64 :: Integer -> Integer-clip64 = min 9223372036854775807 . max (-9223372036854775808)+i64int :: ConnL Int64 (Maybe Integer)+i64int = signed -unsigned :: (Bounded a, Preorder b, Integral a, Integral b) => ConnL a b-unsigned = ConnL f g where-  f = fromIntegral . max 0-  g = fromIntegral . min (f P.maxBound)+ixxint :: ConnL Int (Maybe Integer)+ixxint = signed -signed' :: forall a k. (Bounded a, Integral a) => Conn k a (Extended Integer)-signed' = Conn f g h where-  f = liftExtended (~~ P.minBound) (const False) fromIntegral-  g = extended P.minBound P.maxBound $ P.fromInteger . min (fromIntegral @a P.maxBound) . max (fromIntegral @a P.minBound)-  h = liftExtended (const False) (~~ P.maxBound) fromIntegral--}+---------------------------------------------------------------------+-- Internal+--------------------------------------------------------------------- +fromPred :: (a -> Bool) -> a -> Maybe a+fromPred p a = a <$ guard (p a) +signed :: forall a b. (Bounded a, Integral a, Integral b) => ConnL a (Maybe b)+signed = ConnL f g+  where+    f = fmap fromIntegral . fromPred (/= minBound)+    g = maybe minBound $ fromIntegral @b . min (fromIntegral @a maxBound) . max (fromIntegral @a minBound)
src/Data/Connection/Property.hs view
@@ -1,8 +1,8 @@-{-# Language DataKinds #-}-{-# Language TypeFamilies #-}-{-# Language TypeApplications #-}-{-# Language ConstraintKinds #-}-{-# Language RankNTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}  -- | Galois connections have the same properties as adjunctions defined over other categories: --@@ -23,24 +23,22 @@ --  \( \forall x : counit \circ f (x) \sim f (x) \) -- --  \( \forall x : unit \circ g (x) \sim g (x) \)--- module Data.Connection.Property where +import Data.Connection import Data.Order import Data.Order.Property-import Data.Connection-import Data.Connection.Conn-import Prelude hiding (Num(..),Ord(..), floor, ceiling)+import Prelude hiding (Num (..), Ord (..), ceiling, floor)  -- | \( \forall x, y : f \dashv g \Rightarrow f (x) \leq y \Leftrightarrow x \leq g (y) \) -- -- A Galois connection is an adjunction of preorders. This is a required property.----adjoint :: (Preorder a, Preorder b) => Trip a b -> a -> b -> Bool-adjoint t a b = adjointL t a b &&-                adjointR t a b &&-                adjointL (swapL t) b a &&-                adjointR (swapR t) b a+adjoint :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool+adjoint t a b =+    adjointL t a b+        && adjointR t a b+        && adjointL (swapL t) b a+        && adjointR (swapR t) b a  adjointL :: (Preorder a, Preorder b) => ConnL a b -> a -> b -> Bool adjointL (ConnL f g) = adjunction (<~) (<~) f g@@ -51,8 +49,7 @@ -- | \( \forall x : f \dashv g \Rightarrow x \leq g \circ f (x) \) -- -- This is a required property.----closed :: (Preorder a, Preorder b) => Trip a b -> a -> Bool+closed :: (Preorder a, Preorder b) => ConnK a b -> a -> Bool closed t a = closedL t a && closedR t a  closedL :: (Preorder a, Preorder b) => ConnL a b -> a -> Bool@@ -64,8 +61,7 @@ -- | \( \forall x : f \dashv g \Rightarrow x \leq g \circ f (x) \) -- -- This is a required property.----kernel :: (Preorder a, Preorder b) => Trip a b -> b -> Bool+kernel :: (Preorder a, Preorder b) => ConnK a b -> b -> Bool kernel t b = kernelL t b && kernelR t b  kernelL :: (Preorder a, Preorder b) => ConnL a b -> b -> Bool@@ -77,8 +73,7 @@ -- | \( \forall x, y : x \leq y \Rightarrow f (x) \leq f (y) \) -- -- This is a required property.----monotonic :: (Preorder a, Preorder b) => Trip a b -> a -> a -> b -> b -> Bool+monotonic :: (Preorder a, Preorder b) => ConnK a b -> a -> a -> b -> b -> Bool monotonic t a1 a2 b1 b2 = monotonicL t a1 a2 b1 b2 && monotonicR t a1 a2 b1 b2  monotonicR :: (Preorder a, Preorder b) => ConnR a b -> a -> a -> b -> b -> Bool@@ -90,27 +85,24 @@ -- | \( \forall x: f \dashv g \Rightarrow counit \circ f (x) \sim f (x) \wedge unit \circ g (x) \sim g (x) \) -- -- See <https://ncatlab.org/nlab/show/idempotent+adjunction>----idempotent :: (Preorder a, Preorder b) => Trip a b -> a -> b -> Bool+idempotent :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool idempotent t a b = idempotentL t a b && idempotentR t a b  idempotentL :: (Preorder a, Preorder b) => ConnL a b -> a -> b -> Bool-idempotentL c@(ConnL f g) a b = projective (~~) g (unitL c) b && projective (~~) f (counitL c) a+idempotentL c@(ConnL f g) a b = projective (~~) g (upper c) b && projective (~~) f (counit c) a  idempotentR :: (Preorder a, Preorder b) => ConnR a b -> a -> b -> Bool-idempotentR c@(ConnR f g) a b = projective (~~) g (unitR c) a && projective (~~) f (counitR c) b+idempotentR c@(ConnR f g) a b = projective (~~) g (unit c) a && projective (~~) f (lower c) b  --------------------------------------------------------------------- -- Properties of general relations ---------------------------------------------------------------------  -- | \( \forall a, b: a \leq b \Rightarrow f(a) \leq f(b) \)--- monotone :: Rel r Bool -> Rel s Bool -> (r -> s) -> r -> r -> Bool monotone (#) (%) f a b = a # b ==> f a % f b  -- | \( \forall a, b: a \leq b \Rightarrow f(b) \leq f(a) \)--- antitone :: Rel r Bool -> Rel s Bool -> (r -> s) -> r -> r -> Bool antitone (#) (%) f a b = a # b ==> f b % f a @@ -118,26 +110,15 @@ -- -- For example, a monotone Galois connection is defined by @adjunction (<~) (<~)@, -- and an antitone Galois connection is defined by @adjunction (>~) (<~)@.--- adjunction :: Rel r Bool -> Rel s Bool -> (s -> r) -> (r -> s) -> s -> r -> Bool adjunction (#) (%) f g a b = f a # b <=> a % g b -range' :: Triple () a => (a, a)-range' = (floor (), ceiling ())--ordering :: Trip () Ordering-ordering = trip (const GT) (const ()) (const LT)---extremalOrd :: (Total a, P.Bounded a) => Conn k () a---extremalOrd = Conn (const minBound) (const ()) (const maxBound)- -- | \( \forall a: f (g a) \sim a \)--- invertible :: Rel s b -> (s -> r) -> (r -> s) -> s -> b invertible (#) f g a = g (f a) # a  -- | \( \forall a: g \circ f (a) \sim f (a) \) -- -- > idempotent (#) f = projective (#) f f--- projective :: Rel s b -> (r -> s) -> (s -> s) -> r -> b projective (#) f g r = g (f r) # f r
src/Data/Connection/Ratio.hs view
@@ -1,163 +1,158 @@-{-# Language AllowAmbiguousTypes #-}-{-# Language ConstraintKinds     #-}-{-# Language Safe                #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+ module Data.Connection.Ratio (-    Ratio(..) -  , reduce-  , shiftd-  -- * Rational-  , ratf32-  , ratf64-  , rati08-  , rati16-  , rati32-  , rati64-  , ratixx-  , ratint-  -- * Positive-  , posw08-  , posw16-  , posw32-  , posw64-  , poswxx-  , posnat+    Ratio (..),+    reduce,+    shiftd,++    -- * Rational+    ratf32,+    ratf64,+    rati08,+    rati16,+    rati32,+    rati64,+    ratixx,+    ratint,++    -- * Positive+    posw08,+    posw16,+    posw32,+    posw64,+    poswxx,+    posnat, ) where  import safe Data.Connection.Conn+import safe qualified Data.Connection.Float as Float import safe Data.Int import safe Data.Order import safe Data.Order.Extended+import safe Data.Order.Syntax import safe Data.Ratio import safe Data.Word-import safe GHC.Real (Ratio(..), Rational)+import safe GHC.Real (Ratio (..), Rational) import safe Numeric.Natural-import safe Prelude hiding (Ord(..), until)+import safe Prelude hiding (Ord (..), until) import safe qualified Prelude as P-import safe qualified Data.Connection.Float as F32-import safe qualified Data.Connection.Double as F64  -- | A total version of 'GHC.Real.reduce'.--- reduce :: Integral a => Ratio a -> Ratio a reduce (x :% 0) = x :% 0 reduce (x :% y) = (x `quot` d) :% (y `quot` d) where d = gcd x y  -- | Shift by n 'units of least precision' where the ULP is determined by the denominator--- --- This is an analog of 'Data.Connection.Float.shift' for rationals. --+-- This is an analog of 'Data.Connection.Float.shift32' for rationals. shiftd :: Num a => a -> Ratio a -> Ratio a shiftd n (x :% y) = (n + x) :% y  ------------------------------------------------------------------------ Rational+-- Ratio Integer ---------------------------------------------------------------------  rati08 :: Conn k Rational (Extended Int8)-rati08 = signedTriple 127+rati08 = signedTriple  rati16 :: Conn k Rational (Extended Int16)-rati16 = signedTriple 32767+rati16 = signedTriple  rati32 :: Conn k Rational (Extended Int32)-rati32 = signedTriple 2147483647+rati32 = signedTriple  rati64 :: Conn k Rational (Extended Int64)-rati64 = signedTriple 9223372036854775807+rati64 = signedTriple  ratixx :: Conn k Rational (Extended Int)-ratixx = signedTriple 9223372036854775807+ratixx = signedTriple  ratint :: Conn k Rational (Extended Integer)-ratint = Conn f g h where-  -  f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling+ratint = Conn f g h+  where+    f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling -  g = extended ninf pinf P.fromIntegral+    g = extended ninf pinf P.fromIntegral -  h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor+    h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor  ratf32 :: Conn k Rational Float-ratf32 = Conn (toFloating f) (fromFloating g) (toFloating h) where-  f x = let est = P.fromRational x in --F.fromRat'-          if fromFloating g est >~ x-          then est-          else ascendf est (fromFloating g) x-    -  g = flip approxRational 0 +ratf32 = Conn (toFloating f) (fromFloating g) (toFloating h)+  where+    f x =+        let est = P.fromRational x+         in if fromFloating g est >~ x+                then est+                else ascendf est (fromFloating g) x -  h x = let est = P.fromRational x in-          if fromFloating g est <~ x-          then est-          else descendf est (fromFloating g) x+    g = flip approxRational 0 -  ascendf z g1 y = F64.until (\x -> g1 x >~ y) (<~) (F32.shift 1) z+    h x =+        let est = P.fromRational x+         in if fromFloating g est <~ x+                then est+                else descendf est (fromFloating g) x -  descendf z f1 x = F64.until (\y -> f1 y <~ x) (>~) (F32.shift (-1)) z+    ascendf z g1 y = Float.until (\x -> g1 x >~ y) (<~) (Float.shift32 1) z +    descendf z f1 x = Float.until (\y -> f1 y <~ x) (>~) (Float.shift32 (-1)) z+ ratf64 :: Conn k Rational Double-ratf64 = Conn (toFloating f) (fromFloating g) (toFloating h) where-  f x = let est = P.fromRational x in-          if fromFloating g est >~ x-          then est-          else ascendf est (fromFloating g) x-    -  g = flip approxRational 0 +ratf64 = Conn (toFloating f) (fromFloating g) (toFloating h)+  where+    f x =+        let est = P.fromRational x+         in if fromFloating g est >~ x+                then est+                else ascendf est (fromFloating g) x -  h x = let est = P.fromRational x in-          if fromFloating g est <~ x-          then est-          else descendf est (fromFloating g) x+    g = flip approxRational 0 -  ascendf z g1 y = F64.until (\x -> g1 x >~ y) (<~) (F64.shift 1) z+    h x =+        let est = P.fromRational x+         in if fromFloating g est <~ x+                then est+                else descendf est (fromFloating g) x -  descendf z f1 x = F64.until (\y -> f1 y <~ x) (>~) (F64.shift (-1)) z+    ascendf z g1 y = Float.until (\x -> g1 x >~ y) (<~) (Float.shift64 1) z +    descendf z f1 x = Float.until (\y -> f1 y <~ x) (>~) (Float.shift64 (-1)) z+ --------------------------------------------------------------------- -- Ratio Natural --------------------------------------------------------------------- -posw08 :: Conn k Positive (Lowered Word8) -posw08 = unsignedTriple 255+posw08 :: Conn k Positive (Lowered Word8)+posw08 = unsignedTriple -posw16 :: Conn k Positive (Lowered Word16) -posw16 = unsignedTriple 65535+posw16 :: Conn k Positive (Lowered Word16)+posw16 = unsignedTriple -posw32 :: Conn k Positive (Lowered Word32) -posw32 = unsignedTriple 4294967295+posw32 :: Conn k Positive (Lowered Word32)+posw32 = unsignedTriple -posw64 :: Conn k Positive (Lowered Word64) -posw64 = unsignedTriple 18446744073709551615+posw64 :: Conn k Positive (Lowered Word64)+posw64 = unsignedTriple -poswxx :: Conn k Positive (Lowered Word) -poswxx = unsignedTriple 18446744073709551615+poswxx :: Conn k Positive (Lowered Word)+poswxx = unsignedTriple  posnat :: Conn k Positive (Lowered Natural)-posnat = Conn f g h where-  -  f = liftEitherR (\x -> x ~~ nan || x ~~ pinf) P.ceiling+posnat = Conn f g h+  where+    f = liftEitherR (\x -> x ~~ nan || x ~~ pinf) P.ceiling -  g = either P.fromIntegral (const pinf)+    g = either P.fromIntegral (const pinf) -  h = liftEitherR (~~ pinf) $ \x -> if x ~~ nan then 0 else P.floor x+    h = liftEitherR (~~ pinf) $ \x -> if x ~~ nan then 0 else P.floor x  --------------------------------------------------------------------- -- Internal --------------------------------------------------------------------- -{--pabs :: (Lattice a, Eq a, Num a) => a -> a-pabs x = if 0 <~ x then x else negate x--cancel :: (Lattice a, Eq a, Num a) => Ratio a -> Ratio a-cancel (x :% y) = if x < 0 && y < 0 then (pabs x) :% (pabs y) else x :% y---- | An exception-safe version of 'nanf' for rationals.----nanr :: Integral b => (a -> Ratio b) -> Maybe a -> Ratio b-nanr f = maybe (0 :% 0) f--}- pinf :: Num a => Ratio a pinf = 1 :% 0 @@ -167,56 +162,68 @@ nan :: Num a => Ratio a nan = 0 :% 0 -{--intnat :: Conn Integer Natural-intnat = Conn (fromIntegral . max 0) fromIntegral+unsignedTriple :: forall a k. (Bounded a, Integral a) => Conn k Positive (Lowered a)+unsignedTriple = Conn f g h+  where+    f x+        | x ~~ nan = Right maxBound+        | x > high = Right maxBound+        | otherwise = Left $ P.ceiling x -natint :: Conn Natural (Lifted Integer)-natint = Conn (lifts P.fromIntegral) (lifted $ P.fromInteger . max 0)+    g = either P.fromIntegral (const pinf) -ratpos :: Conn k Rational Positive-ratpos = Conn k f g h where-  -  f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling+    h x+        | x ~~ nan = Left minBound+        | x ~~ pinf = Right maxBound+        | x > high = Left maxBound+        | otherwise = Left $ P.floor x -  g = extended minBound maxBound P.fromIntegral+    high = P.fromIntegral @a maxBound -  h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor--}+signedTriple :: forall a k. (Bounded a, Integral a) => Conn k Rational (Extended a)+signedTriple = Conn f g h+  where+    f = liftExtended (~~ ninf) (\x -> x ~~ nan || x > high) $ \x -> if x < low then minBound else P.ceiling x -unsignedTriple :: (Bounded a, Integral a) => Ratio Natural -> Conn k Positive (Lowered a) -unsignedTriple high = Conn f g h where-  f x | x ~~ nan = Right maxBound-      | x > high = Right maxBound-      | otherwise = Left $ P.ceiling x+    g = extended ninf pinf P.fromIntegral -  g = either P.fromIntegral (const pinf)+    h = liftExtended (\x -> x ~~ nan || x < low) (~~ pinf) $ \x -> if x > high then maxBound else P.floor x -  h x | x ~~ nan = Left minBound-      | x ~~ pinf = Right maxBound-      | x > high = Left maxBound-      | otherwise = Left $ P.floor x+    high = P.fromIntegral @a maxBound+    low = -1 - high -signedTriple :: (Bounded a, Integral a) => Rational -> Conn k Rational (Extended a)-signedTriple high = Conn f g h where+toFloating :: Fractional a => (Rational -> a) -> Rational -> a+toFloating f x+    | x ~~ nan = 0 / 0+    | x ~~ ninf = (-1) / 0+    | x ~~ pinf = 1 / 0+    | otherwise = f x -  f = liftExtended (~~ ninf) (\x -> x ~~ nan || x > high) $ \x -> if x < low then minBound else P.ceiling x+fromFloating :: (Order a, Fractional a) => (a -> Rational) -> a -> Rational+fromFloating f x+    | x ~~ 0 / 0 = nan+    | x ~~ (-1) / 0 = ninf+    | x ~~ 1 / 0 = pinf+    | otherwise = f x -  g = extended ninf pinf P.fromIntegral- -  h = liftExtended (\x -> x ~~ nan || x < low) (~~ pinf) $ \x -> if x > high then maxBound else P.floor x+{-+pabs :: (Lattice a, Eq a, Num a) => a -> a+pabs x = if 0 <~ x then x else negate x -  low = -1 - high+cancel :: (Lattice a, Eq a, Num a) => Ratio a -> Ratio a+cancel (x :% y) = if x < 0 && y < 0 then (pabs x) :% (pabs y) else x :% y +-- | An exception-safe version of 'nanf' for rationals.+--+nanr :: Integral b => (a -> Ratio b) -> Maybe a -> Ratio b+nanr f = maybe (0 :% 0) f -toFloating :: (Order (Ratio a), Fractional b, Num a) => (Ratio a -> b) -> Ratio a -> b-toFloating f x | x ~~ nan = 0/0-         | x ~~ ninf = (-1)/0-         | x ~~ pinf = 1/0-         | otherwise = f x+ratpos :: Conn k Rational Positive+ratpos = Conn k f g h where -fromFloating :: (Order a, Eq a, Fractional a, Num b) => (a -> Ratio b) -> a -> Ratio b-fromFloating f x | x ~~ 0/0 = nan-                 | x ~~ (-1)/0 = ninf-                 | x ~~ 1/0 = pinf-                 | otherwise = f x+  f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling++  g = extended minBound maxBound P.fromIntegral++  h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor+-}
src/Data/Connection/Word.hs view
@@ -1,145 +1,185 @@-{-# Language Safe                #-}+{-# LANGUAGE Safe #-}+ module Data.Connection.Word (-  -- * Bool-    c08bin-  , binc08-  -- * Word8-  , w08c08-  , w08i08-  , w08w16-  , w08w32-  , w08w64-  , w08wxx-  , w08nat-  -- * Word16-  , w16c16-  , w16i16-  , w16w32-  , w16w64-  , w16wxx-  , w16nat-  -- * Word32-  , w32c32-  , w32i32-  , w32w64-  , w32wxx-  , w32nat-  -- * Word64-  , w64c64-  , w64i64-  , w64nat-  -- * Word-  , wxxw64-  , wxxnat+    -- * Word8+    i08w08,++    -- * Word16+    w08w16,+    i08w16,+    i16w16,++    -- * Word32+    w08w32,+    w16w32,+    i08w32,+    i16w32,+    i32w32,++    -- * Word64+    w08w64,+    w16w64,+    w32w64,+    i08w64,+    i16w64,+    i32w64,+    i64w64,+    ixxw64,++    -- * Word+    w08wxx,+    w16wxx,+    w32wxx,+    w64wxx,+    i08wxx,+    i16wxx,+    i32wxx,+    i64wxx,+    ixxwxx,++    -- * Natural+    w08nat,+    w16nat,+    w32nat,+    w64nat,+    wxxnat,+    i08nat,+    i16nat,+    i32nat,+    i64nat,+    ixxnat,+    intnat, ) where  import safe Data.Connection.Conn import safe Data.Int-import safe Data.Order-import safe Data.Order.Syntax import safe Data.Word-import safe Foreign.C.Types import safe Numeric.Natural-import safe Prelude hiding (Ord(..), Eq(..)) -c08bin :: ConnL CBool Bool-c08bin = ConnL f g where-  f (CBool i) | i == 255 = True-              | otherwise = False-  -  g True = CBool 255-  g _ = CBool 254+-- Word8+i08w08 :: ConnL Int8 Word8+i08w08 = unsigned -binc08 :: ConnL Bool CBool-binc08 = ConnL f g where-  f False = CBool 0-  f _ = CBool 1+-- Word16+w08w16 :: ConnL Word8 Word16+w08w16 = unsigned -  g (CBool i) | i == 0 = False-              | otherwise = True+i08w16 :: ConnL Int8 Word16+i08w16 = unsigned -w08c08 :: ConnL Word8 CUChar-w08c08 = ConnL CUChar $ \(CUChar x) -> x+i16w16 :: ConnL Int16 Word16+i16w16 = unsigned -w08i08 :: ConnL Word8 Int8-w08i08 = signed+-- Word32+w08w32 :: ConnL Word8 Word32+w08w32 = unsigned -w08nat :: ConnL Word8 Natural-w08nat = unsigned+w16w32 :: ConnL Word16 Word32+w16w32 = unsigned -w08w16 :: ConnL Word8 Word16-w08w16 = unsigned+i08w32 :: ConnL Int8 Word32+i08w32 = unsigned --- w08w32 = w08w16 >>> w16w32-w08w32 :: ConnL Word8 Word32-w08w32 = unsigned+i16w32 :: ConnL Int16 Word32+i16w32 = unsigned --- w08w64 = w08w32 >>> w32w64 = w08w16 >>> w16w64+i32w32 :: ConnL Int32 Word32+i32w32 = unsigned++-- Word64 w08w64 :: ConnL Word8 Word64 w08w64 = unsigned -w08wxx :: ConnL Word8 Word-w08wxx = unsigned+w16w64 :: ConnL Word16 Word64+w16w64 = unsigned -w16c16 :: ConnL Word16 CUShort-w16c16 = ConnL CUShort $ \(CUShort x) -> x+w32w64 :: ConnL Word32 Word64+w32w64 = unsigned -w16i16 :: ConnL Word16 Int16-w16i16 = signed+i08w64 :: ConnL Int8 Word64+i08w64 = unsigned -w16w32 :: ConnL Word16 Word32-w16w32 = unsigned+i16w64 :: ConnL Int16 Word64+i16w64 = unsigned --- w16w64 = w16w32 >>> w32w64-w16w64 :: ConnL Word16 Word64-w16w64 = unsigned+i32w64 :: ConnL Int32 Word64+i32w64 = unsigned +i64w64 :: ConnL Int64 Word64+i64w64 = unsigned++ixxw64 :: ConnL Int Word64+ixxw64 = unsigned++-- Word+w08wxx :: ConnL Word8 Word+w08wxx = unsigned+ w16wxx :: ConnL Word16 Word w16wxx = unsigned -w16nat :: ConnL Word16 Natural-w16nat = unsigned+w32wxx :: ConnL Word32 Word+w32wxx = unsigned -w32c32 :: ConnL Word32 CUInt-w32c32 = ConnL CUInt $ \(CUInt x) -> x+-- | /Caution/: This assumes that 'Word' on your system is 64 bits.+w64wxx :: Conn k Word64 Word+w64wxx = Conn fromIntegral fromIntegral fromIntegral -w32i32 :: ConnL Word32 Int32-w32i32 = signed+i08wxx :: ConnL Int8 Word+i08wxx = unsigned -w32w64 :: ConnL Word32 Word64-w32w64 = unsigned+i16wxx :: ConnL Int16 Word+i16wxx = unsigned -w32wxx :: ConnL Word32 Word-w32wxx = unsigned+i32wxx :: ConnL Int32 Word+i32wxx = unsigned -w32nat :: ConnL Word32 Natural-w32nat = unsigned+i64wxx :: ConnL Int64 Word+i64wxx = unsigned -w64c64 :: ConnL Word64 CULong-w64c64 = ConnL CULong $ \(CULong x) -> x+ixxwxx :: ConnL Int Word+ixxwxx = unsigned -w64i64 :: ConnL Word64 Int64-w64i64 = signed+-- Natural+w08nat :: ConnL Word8 Natural+w08nat = unsigned +w16nat :: ConnL Word16 Natural+w16nat = unsigned++w32nat :: ConnL Word32 Natural+w32nat = unsigned+ w64nat :: ConnL Word64 Natural w64nat = unsigned --- | /Caution/: This assumes that 'Word' on your system is 64 bits.-wxxw64 :: Conn k Word Word64-wxxw64 = Conn fromIntegral fromIntegral fromIntegral---- | /Caution/: This assumes that 'Word' on your system is 64 bits. wxxnat :: ConnL Word Natural-wxxnat = ConnL fromIntegral (fromIntegral . min 18446744073709551615)+wxxnat = unsigned +i08nat :: ConnL Int8 Natural+i08nat = unsigned++i16nat :: ConnL Int16 Natural+i16nat = unsigned++i32nat :: ConnL Int32 Natural+i32nat = unsigned++i64nat :: ConnL Int64 Natural+i64nat = unsigned++ixxnat :: ConnL Int Natural+ixxnat = unsigned++intnat :: ConnL Integer Natural+intnat = ConnL (fromIntegral . max 0) fromIntegral+ --------------------------------------------------------------------- -- Internal ----------------------------------------------------------------------signed :: (Bounded b, Integral a, Integral b) => ConnL a b-signed = ConnL (\x -> fromIntegral x - minBound)-               (\y -> fromIntegral (y + maxBound + 1)) -unsigned :: (Bounded a, Preorder b, Integral a, Integral b) => ConnL a b-unsigned = ConnL f g where-  f = fromIntegral-  g = fromIntegral . min (f maxBound)+unsigned :: (Bounded a, Integral a, Integral b) => ConnL a b+unsigned = ConnL f g+  where+    f = fromIntegral . max 0+    g = fromIntegral . min (f maxBound)
src/Data/Lattice.hs view
@@ -1,121 +1,202 @@-{-# LANGUAGE Safe                       #-}-{-# LANGUAGE PolyKinds                  #-}-{-# LANGUAGE DataKinds                  #-}-{-# LANGUAGE ConstraintKinds            #-}-{-# LANGUAGE DefaultSignatures          #-}-{-# LANGUAGE DeriveFunctor              #-}-{-# LANGUAGE DeriveGeneric              #-}-{-# LANGUAGE DerivingVia                #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# LANGUAGE StandaloneDeriving         #-}-{-# LANGUAGE TypeOperators              #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+ -- | Lattices & algebras module Data.Lattice (-  -- * Types-    Lattice-  , Semilattice-  -- * HeytingL-  , type HeytingL-  , (\\)-  , non-  , equiv-  , boundary-  , booleanL-  , heytingL-  -- * HeytingR-  , type HeytingR-  , (//)-  , neg-  , iff-  , middle-  , booleanR-  , heytingR-  -- * Heyting-  , (\/)-  , (/\)-  , glb-  , lub-  , true-  , false-  , Heyting(..)-  -- * Symmetric-  , Biheyting-  , Symmetric(..)-  , symmetricL-  , symmetricR-  -- * Boolean-  , Boolean(..)+    -- * Semilattice+    Lattice,+    Semilattice (..),++    -- ** Meet+    Meet,+    (/\),+    top,++    -- ** Join+    Join,+    (\/),+    bottom,++    -- * Algebra+    Biheyting,+    Algebra (..),++    -- ** Heyting+    Heyting,+    (//),+    iff,+    neg,+    middle,+    heyting,+    booleanR,++    -- ** Coheyting+    Coheyting,+    (\\),+    equiv,+    non,+    boundary,+    coheyting,+    booleanL,++    -- ** Symmetric+    Symmetric (..),+    converseL,+    converseR,+    symmetricL,+    symmetricR,++    -- ** Boolean+    Boolean (..), ) where -import safe Control.Applicative import safe Data.Bifunctor (bimap) import safe Data.Bool hiding (not)-import safe Data.Connection.Conn import safe Data.Connection.Class+import safe Data.Connection.Conn import safe Data.Either-import safe Data.Functor.Contravariant-import safe Data.Foldable-import safe Data.Order-import safe Data.Order.Extended-import safe Data.Order.Interval-import safe Data.Order.Syntax import safe Data.Int-import safe Data.Maybe-import safe Data.Monoid-import safe Data.Word-import safe GHC.TypeNats---import safe Numeric.Natural-import safe Prelude hiding (Eq(..),Ord(..),Bounded, not) import safe qualified Data.IntMap as IntMap import safe qualified Data.IntSet as IntSet import safe qualified Data.Map as Map-import safe qualified Data.Map.Merge.Lazy as Map+import safe Data.Order+import safe Data.Order.Extended+import safe Data.Order.Syntax import safe qualified Data.Set as Set-import safe qualified Data.Finite as F-import safe qualified Data.Universe.Class as U+import safe Data.Word+import safe Prelude hiding (Eq (..), Ord (..), not) import safe qualified Prelude as P  ------------------------------------------------------------------------------- -- Lattices ------------------------------------------------------------------------------- +type Lattice a = (Join a, Meet a)++-- | A convenience alias for a join semilattice+type Join = Semilattice 'L++-- | A convenience alias for a meet semilattice+type Meet = Semilattice 'R+ -- | Bounded < https://ncatlab.org/nlab/show/lattice lattices >. --+-- A lattice is a partially ordered set in which every two elements have a unique join+-- (least upper bound or supremum) and a unique meet (greatest lower bound or infimum).+--+-- A bounded lattice adds unique elements 'top' and 'bottom', which serve as+-- identities to '\/' and '/\', respectively.+-- -- /Neutrality/: ----- The least and greatest elements of a complete /a/ are given by the unique--- upper and lower adjoints to the function /a -> ()/.+-- @+-- x '\/' 'bottom' = x+-- x '/\' 'top' = x+-- 'glb' 'bottom' x 'top' = x+-- 'lub' 'bottom' x 'top' = x+-- @ --+-- /Associativity/+-- -- @--- x '\/' 'false' = x--- x '/\' 'true' = x--- 'glb' 'false' x 'true' = x--- 'lub' 'false' x 'true' = x+-- x '\/' (y '\/' z) = (x '\/' y) '\/' z+-- x '/\' (y '/\' z) = (x '/\' y) '/\' z -- @ ---type Lattice a = (Eq a, Semilattice 'L a, Extremal 'L a, Semilattice 'R a, Extremal 'R a)+-- /Commutativity/+--+-- @+-- x '\/' y = y '\/' x+-- x '/\' y = y '/\' x+-- @+--+-- /Idempotency/+--+-- @+-- x '\/' x = x+-- x '/\' x = x+-- @+--+-- /Absorption/+--+-- @+-- (x '\/' y) '/\' y = y+-- (x '/\' y) '\/' y = y+-- @+--+-- See < https://en.wikipedia.org/wiki/Absorption_law Absorption >.+--+-- Note that distributivity is _not_ a requirement for a complete.+-- However when /a/ is distributive we have:+--+-- @+-- 'glb' x y z = 'lub' x y z+-- @+--+-- See < https://en.wikipedia.org/wiki/Lattice_(order) >.+class Order a => Semilattice (k :: Kan) a where+    -- | The defining connection of a bounded semilattice.+    --+    -- 'bottom' and 'top' are defined by the left and right adjoints to /a -> ()/.+    bounded :: Conn k () a+    default bounded :: Connection k () a => Conn k () a+    bounded = conn +    -- | The defining connection of a semilattice.+    --+    -- '\/' and '/\' are defined by the left and right adjoints to /a -> (a, a)/.+    semilattice :: Conn k (a, a) a+    default semilattice :: Connection k (a, a) a => Conn k (a, a) a+    semilattice = conn++infixr 6 /\ -- comment for the parser++-- | Lattice meet.+--+-- > (/\) = curry $ floorWith semilattice+(/\) :: Meet a => a -> a -> a+(/\) = curry $ floorWith semilattice+ -- | The unique top element of a bounded lattice ----- > x /\ true = x--- > x \/ true = true+-- > x /\ top = x+-- > x \/ top = top+top :: Meet a => a+top = floorWith bounded ()++infixr 5 \/++-- | Lattice join. ---true :: Lattice a => a-true = maximal+-- > (\/) = curry $ ceilingWith semilattice+(\/) :: Join a => a -> a -> a+(\/) = curry $ ceilingWith semilattice  -- | The unique bottom element of a bounded lattice ----- > x /\ false = false--- > x \/ false = x----false :: Lattice a => a-false = minimal+-- > x /\ bottom = bottom+-- > x \/ bottom = x+bottom :: Join a => a+bottom = ceilingWith bounded ()  ------------------------------------------------------------------------------- -- Heyting algebras ------------------------------------------------------------------------------- +-- | A convenience alias for a Heyting algebra.+type Heyting a = (Lattice a, Algebra 'R a)++-- | A convenience alias for a < https://ncatlab.org/nlab/show/co-Heyting+algebra co-Heyting algebra >.+type Coheyting a = (Lattice a, Algebra 'L a)+ -- | A < https://ncatlab.org/nlab/show/co-Heyting+algebra bi-Heyting algebra >. -- -- /Laws/:@@ -123,30 +204,21 @@ -- > neg x <= non x -- -- with equality occurring iff /a/ is a 'Boolean' algebra.----type Biheyting a = (HeytingL a, HeytingR a)---- | A convenience alias for a < https://ncatlab.org/nlab/show/co-Heyting+algebra co-Heyting algebra >.----type HeytingL = Heyting 'L---- | A convenience alias for a Heyting algebra.----type HeytingR = Heyting 'R+type Biheyting a = (Coheyting a, Heyting a) --- | Heyting algebras+-- | Heyting and co-Heyting algebras ----- A Heyting algebra is a bounded, distributive complete equipped with an+-- A Heyting algebra is a bounded, distributive lattice equipped with an -- implication operation. ----- * The complete of closed subsets of a trueological space is the primordial--- example of a /HeytingL/ (co-Heyting) algebra.+-- * The complete of closed subsets of a topological space is the primordial+-- example of a /Coheyting/ (co-Algebra) algebra. ----- * The dual complete of open subsets of a trueological space is likewise--- the primordial example of a /HeytingR/ algebra.+-- * The dual complete of open subsets of a topological space is likewise+-- the primordial example of a /Heyting/ algebra. ----- /Heyting 'L/:--- +-- /Coheyting/:+-- -- Co-implication to /a/ is the lower adjoint of disjunction with /a/: -- -- > x \\ a <= y <=> x <= y \/ a@@ -155,12 +227,12 @@ -- -- > EQ /\ non EQ = EQ /\ GT \\ EQ = EQ /\ GT = EQ /= LT ----- See < https://ncatlab.org/nlab/show/co-Heyting+algebra >+-- See < https://ncatlab.org/nlab/show/co-Algebra+algebra > ----- /Heyting 'R/:+-- /Heyting/: -- -- Implication from /a/ is the upper adjoint of conjunction with /a/:--- +-- -- > x <= a // y <=> a /\ x <= y -- -- Similarly, Heyting algebras needn't obey the law of the excluded middle:@@ -168,20 +240,94 @@ -- > EQ \/ neg EQ = EQ \/ EQ // LT = EQ \/ LT = EQ /= GT -- -- See < https://ncatlab.org/nlab/show/Heyting+algebra >----class Lattice a => Heyting k a where-    +class Semilattice k a => Algebra k a where     -- | The defining connection of a (co-)Heyting algebra.     ---    -- > heyting @'L x = ConnL (\\ x) (\/ x) -    -- > heyting @'R x = ConnR (x /\) (x //)-    ---    heyting :: a -> Conn k a a+    -- > algebra @'L x = ConnL (\\ x) (\/ x)+    -- > algebra @'R x = ConnR (x /\) (x //)+    algebra :: a -> Conn k a a  ---------------------------------------------------------------------------------- HeytingL+-- Heyting ------------------------------------------------------------------------------- +infixr 8 // -- same as ^++-- | Logical implication:+--+-- \( a \Rightarrow b = \vee \{x \mid x \wedge a \leq b \} \)+--+-- /Laws/:+--+-- > x /\ y <= z <=> x <= y // z+-- > x // y <= x // (y \/ z)+-- > x <= y => z // x <= z // y+-- > y <= x // (x /\ y)+-- > x <= y <=> x // y = top+-- > (x \/ z) // y <= x // y+-- > (x /\ y) // z = x // y // z+-- > x // (y /\ z) = x // y /\ x // z+-- > x /\ x // y = x /\ y+--+-- >>> False // False+-- True+-- >>> False // True+-- True+-- >>> True // False+-- False+-- >>> True // True+-- True+(//) :: Algebra 'R a => a -> a -> a+(//) = floorWith . algebra++-- | Intuitionistic equivalence.+--+-- When @a@ is /Bool/ this is 'if-and-only-if'.+iff :: Algebra 'R a => a -> a -> a+iff x y = (x // y) /\ (y // x)++-- | Logical negation.+--+-- @ 'neg' x = x '//' 'bottom' @+--+-- /Laws/:+--+-- > neg bottom = top+-- > neg top = bottom+-- > x <= neg (neg x)+-- > neg (x \/ y) <= neg x+-- > neg (x // y) = neg (neg x) /\ neg y+-- > neg (x \/ y) = neg x /\ neg y+-- > x /\ neg x = bottom+-- > neg (neg (neg x)) = neg x+-- > neg (neg (x \/ neg x)) = top+--+-- Some logics may in addition obey < https://ncatlab.org/nlab/show/De+Morgan+Algebra+algebra De Morgan conditions >.+neg :: Heyting a => a -> a+neg x = x // bottom++-- | The Algebra (< https://ncatlab.org/nlab/show/excluded+middle not necessarily excluded>) middle operator.+middle :: Heyting a => a -> a+middle x = x \/ neg x++-- | Default constructor for a Algebra algebra.+heyting :: Meet a => (a -> a -> a) -> a -> ConnR a a+heyting f a = ConnR (a /\) (a `f`)++-- | An adjunction between a Algebra algebra and its Boolean sub-algebra.+--+-- Double negation is a meet-preserving monad.+booleanR :: Heyting a => ConnR a a+booleanR =+    let -- Check that /x/ is a regular element+        -- See https://ncatlab.org/nlab/show/regular+element+        inj x = if x ~~ (neg . neg) x then x else bottom+     in ConnR (neg . neg) inj++-------------------------------------------------------------------------------+-- Coheyting+-------------------------------------------------------------------------------+ infixl 8 \\  -- | Logical co-implication:@@ -189,12 +335,12 @@ -- \( a \Rightarrow b = \wedge \{x \mid a \leq b \vee x \} \) -- -- /Laws/:--- +-- -- > x \\ y <= z <=> x <= y \/ z -- > x \\ y >= (x /\ z) \\ y -- > x >= y => x \\ z >= y \\ z -- > x >= x \\ y--- > x >= y <=> y \\ x = false+-- > x >= y <=> y \\ x = bottom -- > x \\ (y /\ z) >= x \\ y -- > z \\ (x \/ y) = z \\ x \\ y -- > (y \/ z) \\ x = y \\ x \/ z \\ x@@ -216,147 +362,52 @@ -- fromList [EQ,GT] -- >>> [GT,EQ] \\ [LT] -- fromList [EQ,GT]--- -(\\) :: Heyting 'L a => a -> a -> a-(\\) = flip $ lowerL . heyting+(\\) :: Algebra 'L a => a -> a -> a+(\\) = flip $ ceilingWith . algebra +-- | Intuitionistic co-equivalence.+equiv :: Algebra 'L a => a -> a -> a+equiv x y = (x \\ y) \/ (y \\ x)+ -- | Logical < https://ncatlab.org/nlab/show/co-Heyting+negation co-negation >. ----- @ 'non' x = 'true' '\\' x @+-- @ 'non' x = 'top' '\\' x @ -- -- /Laws/:--- --- > non false = true--- > non true = false+--+-- > non bottom = top+-- > non top = bottom -- > x >= non (non x) -- > non (x /\ y) >= non x -- > non (y \\ x) = non (non x) \/ non y -- > non (x /\ y) = non x \/ non y--- > x \/ non x = true+-- > x \/ non x = top -- > non (non (non x)) = non x--- > non (non (x /\ non x)) = false----non :: Heyting 'L a => a -> a-non x = true \\ x---- | Intuitionistic co-equivalence.----equiv :: Heyting 'L a => a -> a -> a-equiv x y = (x \\ y) \/ (y \\ x)+-- > non (non (x /\ non x)) = bottom+non :: Coheyting a => a -> a+non x = top \\ x --- | The co-Heyting < https://ncatlab.org/nlab/show/co-Heyting+boundary boundary > operator.    +-- | The co-Heyting < https://ncatlab.org/nlab/show/co-Heyting+boundary boundary > operator. -- -- > x = boundary x \/ (non . non) x -- > boundary (x /\ y) = (boundary x /\ y) \/ (x /\ boundary y)  -- (Leibniz rule) -- > boundary (x \/ y) \/ boundary (x /\ y) = boundary x \/ boundary y----boundary :: Heyting 'L a => a -> a+boundary :: Coheyting a => a -> a boundary x = x /\ non x +-- | Default constructor for a co-Heyting algebra.+coheyting :: Join a => (a -> a -> a) -> a -> ConnL a a+coheyting f a = ConnL (`f` a) (\/ a)+ -- | An adjunction between a co-Heyting algebra and its Boolean sub-algebra. -- -- Double negation is a join-preserving comonad.----booleanL :: Heyting 'L a => Conn 'L a a+booleanL :: Coheyting a => ConnL a a booleanL =-  let -    -- Check that /x/ is a regular element-    -- See https://ncatlab.org/nlab/show/regular+element-    inj x = if x == (non . non) x then x else true--  in-    ConnL inj (non . non)---- | Default constructor for a co-Heyting algebra.----heytingL :: Lattice a => (a -> a -> a) -> a -> Conn 'L a a-heytingL f a = ConnL (`f` a) (\/ a)------------------------------------------------------------------------------------ HeytingR----------------------------------------------------------------------------------infixr 8 // -- same as ^---- | Logical implication:------ \( a \Rightarrow b = \vee \{x \mid x \wedge a \leq b \} \)------ /Laws/:------ > x /\ y <= z <=> x <= y // z--- > x // y <= x // (y \/ z)--- > x <= y => z // x <= z // y--- > y <= x // (x /\ y)--- > x <= y <=> x // y = true--- > (x \/ z) // y <= x // y--- > (x /\ y) // z = x // y // z--- > x // (y /\ z) = x // y /\ x // z--- > x /\ x // y = x /\ y------ >>> False // False--- True--- >>> False // True--- True--- >>> True // False--- False--- >>> True // True--- True----(//) :: Heyting 'R a => a -> a -> a-(//) x = upperR $ heyting x---- | Logical negation.------ @ 'neg' x = x '//' 'false' @------ /Laws/:------ > neg false = true--- > neg true = false--- > x <= neg (neg x)--- > neg (x \/ y) <= neg x--- > neg (x // y) = neg (neg x) /\ neg y--- > neg (x \/ y) = neg x /\ neg y--- > x /\ neg x = false--- > neg (neg (neg x)) = neg x--- > neg (neg (x \/ neg x)) = true------ Some logics may in addition obey < https://ncatlab.org/nlab/show/De+Morgan+Heyting+algebra De Morgan conditions >.----neg :: Heyting 'R a => a -> a-neg x = x // false---- | Intuitionistic equivalence.------ When /a=Bool/ this is 'if-and-only-if'.----iff :: Heyting 'R a => a -> a -> a-iff x y = (x // y) /\ (y // x)---- | The Heyting (< https://ncatlab.org/nlab/show/excluded+middle not necessarily excluded>) middle operator.----middle :: Heyting 'R a => a -> a-middle x = x \/ neg x---- | An adjunction between a Heyting algebra and its Boolean sub-algebra.------ Double negation is a meet-preserving monad.----booleanR :: Heyting 'R a => Conn 'R a a-booleanR = -  let-    -- Check that /x/ is a regular element-    -- See https://ncatlab.org/nlab/show/regular+element-    inj x = if x == (neg . neg) x then x else false--  in -    ConnR (neg . neg) inj---- | Default constructor for a Heyting algebra.----heytingR :: Lattice a => (a -> a -> a) -> a -> Conn 'R a a-heytingR f a = ConnR (a /\) (a `f`)+    let -- Check that /x/ is a regular element+        -- See https://ncatlab.org/nlab/show/regular+element+        inj x = if x ~~ (non . non) x then x else top+     in ConnL inj (non . non)  ------------------------------------------------------------------------------- -- Symmetric@@ -364,8 +415,8 @@  -- | Symmetric Heyting algebras ----- A symmetric Heyting algebra is a <https://ncatlab.org/nlab/show/De+Morgan+Heyting+algebra De Morgan >--- bi-Heyting algebra with an idempotent, antitone negation operator.+-- A symmetric Heyting algebra is a <https://ncatlab.org/nlab/show/De+Morgan+Algebra+algebra De Morgan >+-- bi-Algebra algebra with an idempotent, antitone negation operator. -- -- /Laws/: --@@ -379,9 +430,7 @@ -- > converseR x <= converseL x -- -- with equality occurring iff /a/ is a 'Boolean' algebra.--- class Biheyting a => Symmetric a where-     -- | Symmetric negation.     --     -- > not . not = id@@ -394,7 +443,6 @@     -- > non = not . converseR = converseL . not     -- > x \\ y = not (not y // not x)     -- > x // y = not (not y \\ not x)-    --     not :: a -> a      infixl 4 `xor`@@ -402,226 +450,254 @@     -- | Exclusive or.     --     -- > xor x y = (x \/ y) /\ (not x \/ not y)-    --     xor :: a -> a -> a     xor x y = (x \/ y) /\ not (x /\ y) -    -- | Left converse operator.-    --    -    converseL :: a -> a-    converseL x = true \\ not x--    -- | Right converse operator.-    --    -    converseR :: a -> a-    converseR x = not x // false+-- | Left converse operator.+converseL :: Symmetric a => a -> a+converseL x = top \\ not x --- | Default constructor for a co-Heyting algebra.----symmetricL :: Symmetric a => a -> ConnL a a-symmetricL = heytingL $ \x y -> not (not y // not x)+-- | Right converse operator.+converseR :: Symmetric a => a -> a+converseR x = not x // bottom  -- | Default constructor for a Heyting algebra.--- symmetricR :: Symmetric a => a -> ConnR a a-symmetricR = heytingR $ \x y -> not (not y \\ not x)+symmetricR = heyting $ \x y -> not (not y \\ not x) +-- | Default constructor for a co-Heyting algebra.+symmetricL :: Symmetric a => a -> ConnL a a+symmetricL = coheyting $ \x y -> not (not y // not x)+ ------------------------------------------------------------------------------- -- Boolean -------------------------------------------------------------------------------  -- | Boolean algebras. ----- < https://ncatlab.org/nlab/show/Boolean+algebra Boolean algebras > are --- symmetric Heyting algebras that satisfy both the law of excluded middle+-- < https://ncatlab.org/nlab/show/Boolean+algebra Boolean algebras > are+-- symmetric Algebra algebras that satisfy both the law of excluded middle -- and the law of law of non-contradiction: ----- > x \/ neg x = true--- > x /\ non x = false+-- > x \/ neg x = top+-- > x /\ non x = bottom -- -- If /a/ is Boolean we also have: -- -- > non = not = neg--- class Symmetric a => Boolean a where-     -- | A witness to the lawfulness of a boolean algebra.-    ---    boolean :: Trip a a+    boolean :: Conn k a a     boolean = Conn (converseR . converseL) id (converseL . converseR)  ------------------------------------------------------------------------------- -- Instances ------------------------------------------------------------------------------- --impliesL :: (Total a, P.Bounded a) => a -> a -> a-impliesL x y = if y < x then x else P.minBound--impliesR :: (Total a, P.Bounded a) => a -> a -> a-impliesR x y = if x > y then y else P.maxBound--instance Heyting 'L () where heyting = heytingL impliesL-instance Heyting 'L Bool where heyting = heytingL impliesL-instance Heyting 'L Ordering where heyting = heytingL impliesL-instance Heyting 'L Word8 where heyting = heytingL impliesL-instance Heyting 'L Word16 where heyting = heytingL impliesL-instance Heyting 'L Word32 where heyting = heytingL impliesL-instance Heyting 'L Word64 where heyting = heytingL impliesL-instance Heyting 'L Word where heyting = heytingL impliesL-instance KnownNat n => Heyting 'L (F.Finite n) where heyting = heytingL impliesL--instance Heyting 'R () where heyting = heytingR impliesR-instance Heyting 'R Bool where heyting = heytingR impliesR---instance Heyting 'R Ordering where heyting = heytingR impliesR-instance Heyting 'R Word8 where heyting = heytingR impliesR-instance Heyting 'R Word16 where heyting = heytingR impliesR-instance Heyting 'R Word32 where heyting = heytingR impliesR-instance Heyting 'R Word64 where heyting = heytingR impliesR-instance Heyting 'R Word where heyting = heytingR impliesR-instance KnownNat n => Heyting 'R (F.Finite n) where heyting = heytingR impliesR--instance Heyting 'L Int8 where heyting = heytingL impliesL-instance Heyting 'L Int16 where heyting = heytingL impliesL-instance Heyting 'L Int32 where heyting = heytingL impliesL-instance Heyting 'L Int64 where heyting = heytingL impliesL-instance Heyting 'L Int where heyting = heytingL impliesL-instance Heyting 'R Int8 where heyting = heytingR impliesR-instance Heyting 'R Int16 where heyting = heytingR impliesR-instance Heyting 'R Int32 where heyting = heytingR impliesR-instance Heyting 'R Int64 where heyting = heytingR impliesR-instance Heyting 'R Int where heyting = heytingR impliesR+instance Semilattice k ()+instance Algebra 'L () where algebra = coheyting impliesL+instance Algebra 'R () where algebra = heyting impliesR+instance Symmetric () where not = id+instance Boolean () -instance Symmetric () where not _ = ()+instance Semilattice k Bool+instance Algebra 'L Bool where algebra = coheyting impliesL+instance Algebra 'R Bool where algebra = heyting impliesR instance Symmetric Bool where not = P.not-instance Symmetric Ordering where-  not LT = GT-  not EQ = EQ-  not GT = LT- -instance Heyting 'R Ordering where heyting = symmetricR--instance Boolean () instance Boolean Bool ----------------------------------------------------------------------------------- Instances: sum types--------------------------------------------------------------------------------+instance Semilattice k Ordering+instance Algebra 'L Ordering where algebra = coheyting impliesL+instance Algebra 'R Ordering where algebra = heyting impliesR+instance Symmetric Ordering where+    not LT = GT+    not EQ = EQ+    not GT = LT+instance Boolean Ordering +instance Semilattice k Word8+instance Algebra 'L Word8 where algebra = coheyting impliesL+instance Algebra 'R Word8 where algebra = heyting impliesR +instance Semilattice k Word16+instance Algebra 'L Word16 where algebra = coheyting impliesL+instance Algebra 'R Word16 where algebra = heyting impliesR --- |--- Subdirectly irreducible Heyting algebra.-instance Heyting 'R a => Heyting 'R (Lowered a) where-  heyting = heytingR f where+instance Semilattice k Word32+instance Algebra 'L Word32 where algebra = coheyting impliesL+instance Algebra 'R Word32 where algebra = heyting impliesR -    (Left a)  `f` (Left b) | a <= b    = true-                           | otherwise = Left (a // b)-    (Right _) `f` a                    = a-    _         `f` (Right _)            = true+instance Semilattice k Word64+instance Algebra 'L Word64 where algebra = coheyting impliesL+instance Algebra 'R Word64 where algebra = heyting impliesR -instance Heyting 'R a => Heyting 'R (Lifted a) where-  heyting = heytingR f where-    f (Right a) (Right b) = Right (a // b)-    f (Left _)   _        = Right true-    f _         (Left _)  = false+instance Semilattice k Word+instance Algebra 'L Word where algebra = coheyting impliesL+instance Algebra 'R Word where algebra = heyting impliesR -instance Heyting 'R a => Heyting 'R (Maybe a) where-  heyting = heytingR f where-    f (Just a) (Just b)   = Just (a // b)-    f Nothing  _          = Just true-    f _        Nothing    = Nothing+instance Semilattice k Int8+instance Algebra 'L Int8 where algebra = coheyting impliesL+instance Algebra 'R Int8 where algebra = heyting impliesR ---instance Complete k a => Complete k (Extended a)-instance Heyting 'R a => Heyting 'R (Extended a) where-  heyting = heytingR f where+instance Semilattice k Int16+instance Algebra 'L Int16 where algebra = coheyting impliesL+instance Algebra 'R Int16 where algebra = heyting impliesR -    Extended a `f` Extended b | a <= b    = Top-                              | otherwise = Extended (a // b)-    Top        `f` a          = a-    _          `f` Top        = Top-    Bottom     `f` _          = Top-    _          `f` Bottom     = Bottom+instance Semilattice k Int32+instance Algebra 'L Int32 where algebra = coheyting impliesL+instance Algebra 'R Int32 where algebra = heyting impliesR ---instance Symmetric a => Symmetric (Extended a) where+instance Semilattice k Int64+instance Algebra 'L Int64 where algebra = coheyting impliesL+instance Algebra 'R Int64 where algebra = heyting impliesR +instance Semilattice k Int+instance Algebra 'L Int where algebra = coheyting impliesL+instance Algebra 'R Int where algebra = heyting impliesR+ ------------------------------------------------------------------------------- -- Instances: product types ------------------------------------------------------------------------------- -instance (Heyting k a, Heyting k b) => Heyting k (a, b) where-  heyting (a,b) = heyting a `strong` heyting b+instance (Lattice a, Lattice b) => Semilattice k (a, b) where+    bounded = Conn (const (bottom, bottom)) (const ()) (const (top, top))+    semilattice = Conn (uncurry joinTuple) fork (uncurry meetTuple) +instance (Heyting a, Heyting b) => Algebra 'R (a, b) where+    algebra (a, b) = algebra a `strong` algebra b++instance (Coheyting a, Coheyting b) => Algebra 'L (a, b) where+    algebra (a, b) = algebra a `strong` algebra b+ instance (Symmetric a, Symmetric b) => Symmetric (a, b) where-  not = bimap not not+    not = bimap not not -instance (Boolean a, Boolean b) => Boolean (a, b) where+instance (Boolean a, Boolean b) => Boolean (a, b)  ---------------------------------------------------------------------------------- Instances: function types+-- Instances: sum types ------------------------------------------------------------------------------- +instance Join a => Semilattice 'L (Maybe a) where+    bounded = ConnL (const Nothing) (const ())+    semilattice = ConnL (uncurry joinMaybe) fork -instance (U.Finite a, Biheyting b) => Heyting 'L (a -> b) where-  heyting = heytingL $ liftA2 (\\)+instance Meet a => Semilattice 'R (Maybe a) where+    bounded = ConnR (const ()) (const $ Just top)+    semilattice = ConnR fork (uncurry meetMaybe) -instance (U.Finite a, Biheyting b) => Heyting 'R (a -> b) where-  heyting = heytingR $ liftA2 (//)+instance Heyting a => Algebra 'R (Maybe a) where+    algebra = heyting f+      where+        f (Just a) (Just b) = Just (a // b)+        f Nothing _ = Just top+        f _ Nothing = Nothing -instance (U.Finite a, Symmetric b) => Symmetric (a -> b) where not = fmap not+instance Join a => Semilattice 'L (Extended a) where+    bounded = Conn (const Bottom) (const ()) (const Top)+    semilattice = ConnL (uncurry joinExtended) fork -instance (U.Finite a, Boolean b) => Boolean (a -> b)+instance Meet a => Semilattice 'R (Extended a) where+    bounded = Conn (const Bottom) (const ()) (const Top)+    semilattice = ConnR fork (uncurry meetExtended) -deriving via (a -> a) instance (U.Finite a, Biheyting a) => Heyting 'L (Endo a)-deriving via (a -> a) instance (U.Finite a, Biheyting a) => Heyting 'R (Endo a)-instance (U.Finite a, Symmetric a) => Symmetric (Endo a)-instance (U.Finite a, Boolean a) => Boolean (Endo a)+instance Heyting a => Algebra 'R (Extended a) where+    algebra = heyting f+      where+        Extended a `f` Extended b+            | a <~ b = Top+            | otherwise = Extended (a // b)+        Top `f` a = a+        _ `f` Top = Top+        Bottom `f` _ = Top+        _ `f` Bottom = Bottom -deriving via (a -> b) instance (U.Finite a, Biheyting b) => Heyting 'L (Op b a)-deriving via (a -> b) instance (U.Finite a, Biheyting b) => Heyting 'R (Op b a)-instance (U.Finite a, Symmetric b) => Symmetric (Op b a)-instance (U.Finite a, Boolean b) => Boolean (Op b a)+-- | All minimal elements of the upper lattice cover all maximal elements of the lower lattice.+instance (Join a, Join b) => Semilattice 'L (Either a b) where+    bounded = ConnL (const $ Left bottom) (const ())+    semilattice = ConnL (uncurry joinEither) fork -deriving via (Op Bool a) instance (U.Finite a) => Heyting 'L (Predicate a)-deriving via (Op Bool a) instance (U.Finite a) => Heyting 'R (Predicate a)-instance (U.Finite a) => Symmetric (Predicate a)-instance (U.Finite a) => Boolean (Predicate a)+instance (Meet a, Meet b) => Semilattice 'R (Either a b) where+    bounded = ConnR (const ()) (const $ Right top)+    semilattice = ConnR fork (uncurry meetEither) +-- |+-- Subdirectly irreducible Algebra algebra.+instance Heyting a => Algebra 'R (Lowered a) where+    algebra = heyting f+      where+        (Left a) `f` (Left b)+            | a <~ b = top+            | otherwise = Left (a // b)+        (Right _) `f` a = a+        _ `f` (Right _) = top++instance Heyting a => Algebra 'R (Lifted a) where+    algebra = heyting f+      where+        f (Right a) (Right b) = Right (a // b)+        f (Left _) _ = Right top+        f _ (Left _) = bottom+ ------------------------------------------------------------------------------- -- Instances: collections ------------------------------------------------------------------------------- +instance Total a => Semilattice 'L (Set.Set a) -instance (Total a, U.Finite a) => Heyting 'L (Set.Set a) where-  heyting = heytingL (Set.\\)+instance Total a => Algebra 'L (Set.Set a) where+    algebra = coheyting (Set.\\) -instance (Total a, U.Finite a) => Heyting 'R (Set.Set a) where-  heyting = symmetricR+--instance (Total a, U.Finite a) => Algebra 'R (Set.Set a) where+--  algebra = symmetricR -instance (Total a, U.Finite a) => Symmetric (Set.Set a) where-  not = non --(U.universe Set.\\)+--instance (Total a, U.Finite a) => Symmetric (Set.Set a) where+--  not = non --(U.universe Set.\\) -instance (Total a, U.Finite a) => Boolean (Set.Set a) where+--instance (Total a, U.Finite a) => Boolean (Set.Set a) where -instance Heyting 'L IntSet.IntSet where-  heyting = heytingL (IntSet.\\)+instance Semilattice 'L IntSet.IntSet -instance Heyting 'R IntSet.IntSet where-  --heyting = heytingR $ \x y -> non x \/ y-  heyting = symmetricR+instance Algebra 'L IntSet.IntSet where+    algebra = coheyting (IntSet.\\) +{-+instance Algebra 'R IntSet.IntSet where+  --heyting = heyting $ \x y -> non x \/ y+  algebra = symmetricR+ instance Symmetric IntSet.IntSet where   not = non --(U.universe IntSet.\\)  instance Boolean IntSet.IntSet where +-}++instance (Total k, Join a) => Semilattice 'L (Map.Map k a) where+    bounded = ConnL (const Map.empty) (const ())++    semilattice = ConnL f fork+      where+        f = uncurry $ Map.unionWith (curry $ ceilingWith semilattice)++instance (Total k, Join a) => Algebra 'L (Map.Map k a) where+    algebra = coheyting (Map.\\)++instance (Join a) => Semilattice 'L (IntMap.IntMap a) where+    bounded = ConnL (const IntMap.empty) (const ())++    semilattice = ConnL f fork+      where+        f = uncurry $ IntMap.unionWith (curry $ ceilingWith semilattice)++instance (Join a) => Algebra 'L (IntMap.IntMap a) where+    algebra = coheyting (IntMap.\\)+ {- TODO pick an instance either key-aware or no-instance (Total a, U.Finite a, Lattice b) => Heyting 'L (Map.Map a b) where-  heyting = heytingL (Map.\\) -instance (Total a, U.Finite a, Heyting 'R b) => Heyting 'R (Map.Map a b) where+instance (Total a, U.Finite a, Heyting b) => Algebra 'R (Map.Map a b) where -  heyting = heytingR $ \a b ->+  algebra = heyting $ \a b ->     let       x = Map.merge             Map.dropMissing                    -- drop if an element is missing in @b@@@ -634,30 +710,29 @@         -- a @true@ key     in       Map.union x y-{-+ -- TODO: compare performance impliesMap a b =   Map.intersection (`implies`) a b     `Map.union` Map.map (const true) (Map.difference b a)     `Map.union` Map.fromList [(k, true) | k <- universeF, not (Map.member k a), not (Map.member k b)]--}--} +-}  {-  -- A symmetric Heyting algebra--- +-- -- λ> implies (False ... True) (False ... True) -- Interval True True -- λ> implies (False ... True) (singleton False) -- Interval False False -- λ> implies (singleton True) (False ... True) -- Interval False True--- +-- -- λ> implies ([EQ,GT] ... [EQ,GT]) ([LT] ... [LT,EQ])  :: Interval (Set.Set Ordering) -- Interval (fromList [LT]) (fromList [LT,EQ])--- +-- -- TODO: may need /a/ to be boolean here. implies :: Symmetric a => Interval a -> Interval a -> Interval a implies i1 i2 = maybe iempty (uncurry (...)) $ liftA2 f (endpts i1) (endpts i2) where@@ -669,11 +744,11 @@ coimplies i1 i2 = not (not i1 `implies` not i2)  -- The symmetry--- neg x = true \\ not x--- non x = not x // false+-- neg x = top \\ not x+-- non x = not x // bottom -- λ> not ([LT] ... [LT,GT]) :: Interval (Set.Set Ordering) -- Interval (fromList [EQ]) (fromList [EQ,GT])--- +-- not :: Symmetric a => Interval a -> Interval a not = maybe iempty (\(x1, x2) -> neg x2 ... neg x1) . endpts @@ -681,16 +756,70 @@ -- Interval False False -- λ> (False ... True) `implies` (singleton False) -- Interval False False--- -neg' x = (false ... true) `coimplies` (not x)+--+neg' x = (bottom ... top) `coimplies` (not x)  -- λ> non' (False ... True) -- Interval False False -- λ> (singleton True) `coimplies` (False ... True) -- Interval False False--- -non' x = not x `implies` (singleton false)+--+non' x = not x `implies` (singleton bottom)  -} +-- Internal +-------------------------+fork :: a -> (a, a)+fork x = (x, x)++impliesL :: (Total a, P.Bounded a) => a -> a -> a+impliesL x y = if y < x then x else P.minBound++impliesR :: (Total a, P.Bounded a) => a -> a -> a+impliesR x y = if x > y then y else P.maxBound++joinTuple :: (Semilattice 'L a, Semilattice 'L b) => (a, b) -> (a, b) -> (a, b)+joinTuple (x1, y1) (x2, y2) = (x1 \/ x2, y1 \/ y2)++meetTuple :: (Semilattice 'R a, Semilattice 'R b) => (a, b) -> (a, b) -> (a, b)+meetTuple (x1, y1) (x2, y2) = (x1 /\ x2, y1 /\ y2)++joinMaybe :: Join a => Maybe a -> Maybe a -> Maybe a+joinMaybe (Just x) (Just y) = Just (x \/ y)+joinMaybe u@(Just _) _ = u+joinMaybe _ u@(Just _) = u+joinMaybe Nothing Nothing = Nothing++meetMaybe :: Meet a => Maybe a -> Maybe a -> Maybe a+meetMaybe Nothing Nothing = Nothing+meetMaybe Nothing _ = Nothing+meetMaybe _ Nothing = Nothing+meetMaybe (Just x) (Just y) = Just (x /\ y)++joinExtended :: Join a => Extended a -> Extended a -> Extended a+joinExtended Top _ = Top+joinExtended _ Top = Top+joinExtended (Extended x) (Extended y) = Extended (x \/ y)+joinExtended Bottom y = y+joinExtended x Bottom = x++meetExtended :: Meet a => Extended a -> Extended a -> Extended a+meetExtended Top y = y+meetExtended x Top = x+meetExtended (Extended x) (Extended y) = Extended (x /\ y)+meetExtended Bottom _ = Bottom+meetExtended _ Bottom = Bottom++joinEither :: (Join a, Join b) => Either a b -> Either a b -> Either a b+joinEither (Right x) (Right y) = Right (x \/ y)+joinEither u@(Right _) _ = u+joinEither _ u@(Right _) = u+joinEither (Left x) (Left y) = Left (x \/ y)++meetEither :: (Meet a, Meet b) => Either a b -> Either a b -> Either a b+meetEither (Left x) (Left y) = Left (x /\ y)+meetEither l@(Left _) _ = l+meetEither _ l@(Left _) = l+meetEither (Right x) (Right y) = Right (x /\ y)
src/Data/Lattice/Property.hs view
@@ -1,178 +1,212 @@-{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+ module Data.Lattice.Property where -import Data.Connection.Conn-import Data.Connection.Property-import Data.Order+import Data.Lattice import Data.Order.Property import Data.Order.Syntax-import Data.Lattice-import Prelude hiding (Eq(..), Ord(..), Bounded, not)+import Prelude hiding (Bounded, Eq (..), Ord (..), not) ---foo x y z = x // y <= x // y /\ z---foo x z y = x /\ z // y <= x // y--- --- x '\\' x           = 'true'--- x '/\' (x '\\' y)  = x '/\' y--- y '/\' (x '\\' y)  = y--- x '\\' (y '\\' z) = (x '/\' y) '\\' z--- x '\\' (y '/\' z)  = (x '\\' y) '/\' (x '\\' z)--- 'neg' (x '/\' y)    = 'neg' (x '\/' y)--- 'neg' (x '\/' y)    = 'neg' x '/\' 'neg' y--- (x '\\' y) '\/' x '<=' y--- y '<=' (x '\\' x '/\' y)--- x '<=' y => (z '\\' x) '<=' (z '\\' y)--- x '<=' y => (x '\\' z) '<=' (y '\\' z)--- x '<=' y <=> x '\\' y '==' 'true'--- x '/\' y '<=' z <=> x '<=' (y '\\' z) <=> y '<=' (x '\\' z)--- ---+coheyting0 :: Coheyting a => a -> a -> a -> Bool+coheyting0 x y z = x \\ y <= z <=> x <= y \/ z +coheyting1 :: Coheyting a => a -> a -> a -> Bool+coheyting1 x y z = x \\ y >= (x /\ z) \\ y --- adjointL $ ConnL (\x -> y \\ not x) (\z -> not z // not y)-symmetric1 x = neg x <= non x-symmetric2 x = (neg . neg) x == (converseR . converseL) x-symmetric3 x = (non . non) x == (converseL . converseR) x-symmetric4 x = non x == (converseL . not) x && neg x == (not . converseL) x-symmetric5 x = non x == (not . converseR) x && neg x == (converseR . not) x-symmetric6 x = neg x \/ neg (neg x) == true-symmetric7 x y = not (x /\ y) == not x \/ not y-symmetric8 x y = (not . not) (x \/ y) == not (not x) \/ not (not y)-symmetric9 x y = not (x \/ y) == not x /\ not y-symmetric10 x y = converseL (x \/ y) == converseL x \/ converseL y-symmetric11 x y = converseR (x /\ y) == converseR x /\ converseR y-symmetric12 x y = converseL (x /\ y) == (non . non) (converseL x /\ converseL y)-symmetric13 x y = converseR (x \/ y) == (neg . neg) (converseR x \/ converseR y)- -boolean0 x = neg x == non x-boolean1 x = neg (neg x) == x-boolean2 x = x \/ neg x == true-boolean3 x = x /\ non x == false -boolean4 x y = (x <= y) // (neg y <= neg x)-boolean5 x y = x \\ y == neg (neg y // neg x)-boolean6 x y = x // y == non (non y \\ non x)+coheyting2 :: Coheyting a => a -> a -> a -> Bool+coheyting2 x y z = x \\ (y /\ z) >= x \\ y +coheyting3 :: Coheyting a => a -> a -> a -> Bool+coheyting3 x y z = x >= y ==> x \\ z >= y \\ z -heytingL0 :: Heyting 'L a => a -> a -> a -> Bool-heytingL0 x y z = x \\ y <= z <=> x <= y \/ z+coheyting4 :: Coheyting a => a -> a -> a -> Bool+coheyting4 x y z = z \\ (x \/ y) == z \\ x \\ y -heytingL1 :: Heyting 'L a => a -> a -> a -> Bool-heytingL1 x y z = x \\ y >= (x /\ z) \\ y+coheyting5 :: Coheyting a => a -> a -> a -> Bool+coheyting5 x y z = (y \/ z) \\ x == y \\ x \/ z \\ x -heytingL2 :: Heyting 'L a => a -> a -> a -> Bool-heytingL2 x y z = x \\ (y /\ z) >= x \\ y+coheyting6 :: Coheyting a => a -> a -> Bool+coheyting6 x y = x >= x \\ y -heytingL3 :: Heyting 'L a => a -> a -> a -> Bool-heytingL3 x y z = x >= y ==> x \\ z >= y \\ z+coheyting7 :: Coheyting a => a -> a -> Bool+coheyting7 x y = x \/ y \\ x == x \/ y -heytingL4 :: Heyting 'L a => a -> a -> a -> Bool-heytingL4 x y z = z \\ (x \/ y) == z \\ x \\ y+coheyting8 :: forall a. Coheyting a => a -> Bool+coheyting8 _ = non bottom == top @a && non top == bottom @a -heytingL5 :: Heyting 'L a => a -> a -> a -> Bool-heytingL5 x y z = (y \/ z) \\ x == y \\ x \/ z \\ x+-- Double co-negation is a co-monad.+coheyting9 :: Coheyting a => a -> a -> Bool+coheyting9 x y = x /\ non y >= x \\ y -heytingL6 :: Heyting 'L a => a -> a -> Bool-heytingL6 x y = x >= x \\ y+coheyting10 :: Coheyting a => a -> a -> Bool+coheyting10 x y = x >= y <=> y \\ x == bottom -heytingL7 :: Heyting 'L a => a -> a -> Bool-heytingL7 x y = x \/ y \\ x == x \/ y+coheyting11 :: Coheyting a => a -> a -> Bool+coheyting11 x y = non (x /\ y) >= non x -heytingL8 :: forall a. Heyting 'L a => a -> Bool-heytingL8 _ = non false == true @a && non true == false @a+coheyting12 :: Coheyting a => a -> a -> Bool+coheyting12 x y = non (y \\ x) == non (non x) \/ non y --- Double co-negation is a co-monad.-heytingL9 :: Heyting 'L a => a -> a -> Bool-heytingL9 x y = x /\ non y >= x \\ y+coheyting13 :: Coheyting a => a -> a -> Bool+coheyting13 x y = non (x /\ y) == non x \/ non y -heytingL10 :: Heyting 'L a => a -> a -> Bool-heytingL10 x y = x >= y <=> y \\ x == false+coheyting14 :: Coheyting a => a -> Bool+coheyting14 x = x \/ non x == top -heytingL11 :: Heyting 'L a => a -> a -> Bool-heytingL11 x y = non (x /\ y) >= non x+coheyting15 :: Coheyting a => a -> Bool+coheyting15 x = non (non (non x)) == non x -heytingL12 :: Heyting 'L a => a -> a -> Bool-heytingL12 x y = non (y \\ x) == non (non x) \/ non y+coheyting16 :: Coheyting a => a -> Bool+coheyting16 x = non (non (x /\ non x)) == bottom -heytingL13 :: Heyting 'L a => a -> a -> Bool-heytingL13 x y = non (x /\ y) == non x \/ non y+coheyting17 :: Coheyting a => a -> Bool+coheyting17 x = x >= non (non x) -heytingL14 :: Heyting 'L a => a -> Bool-heytingL14 x = x \/ non x == true+coheyting18 :: Coheyting c => c -> Bool+coheyting18 x = x == boundary x \/ (non . non) x -heytingL15 :: Heyting 'L a => a -> Bool-heytingL15 x = non (non (non x)) == non x+coheyting19 :: Coheyting a => a -> a -> Bool+coheyting19 x y = boundary (x /\ y) == (boundary x /\ y) \/ (x /\ boundary y) -- (Leibniz rule) -heytingL16 :: Heyting 'L a => a -> Bool-heytingL16 x = non (non (x /\ non x)) == false+coheyting20 :: Coheyting a => a -> a -> Bool+coheyting20 x y = boundary (x \/ y) \/ boundary (x /\ y) == boundary x \/ boundary y -heytingL17 :: Heyting 'L a => a -> Bool-heytingL17 x = x >= non (non x)+heyting0 :: Heyting a => a -> a -> a -> Bool+heyting0 x y z = x /\ y <= z <=> x <= y // z -heytingL18 :: Heyting 'L c => c -> Bool-heytingL18 x = x == boundary x \/ (non . non) x+heyting1 :: Heyting a => a -> a -> a -> Bool+heyting1 x y z = x // y <= x // (y \/ z) -heytingL19 :: Heyting 'L a => a -> a -> Bool-heytingL19 x y = boundary (x /\ y) == (boundary x /\ y) \/ (x /\ boundary y)  -- (Leibniz rule)+heyting2 :: Heyting a => a -> a -> a -> Bool+heyting2 x y z = (x \/ z) // y <= x // y -heytingL20 :: Heyting 'L a => a -> a -> Bool-heytingL20 x y = boundary (x \/ y) \/ boundary (x /\ y) == boundary x \/ boundary y+heyting3 :: Heyting a => a -> a -> a -> Bool+heyting3 x y z = x <= y ==> z // x <= z // y +heyting4 :: Heyting a => a -> a -> a -> Bool+heyting4 x y z = (x /\ y) // z == x // y // z -heytingR0 :: Heyting 'R a => a -> a -> a -> Bool-heytingR0 x y z = x /\ y <= z <=> x <= y // z+heyting5 :: Heyting a => a -> a -> a -> Bool+heyting5 x y z = x // (y /\ z) == x // y /\ x // z -heytingR1 :: Heyting 'R a => a -> a -> a -> Bool-heytingR1 x y z = x // y <= x // (y \/ z)+heyting6 :: Heyting a => a -> a -> Bool+heyting6 x y = y <= x // (x /\ y) -heytingR2 :: Heyting 'R a => a -> a -> a -> Bool-heytingR2 x y z = (x \/ z) // y <= x // y+heyting7 :: Heyting a => a -> a -> Bool+heyting7 x y = x /\ x // y == x /\ y -heytingR3 :: Heyting 'R a => a -> a -> a -> Bool-heytingR3 x y z = x <= y ==> z // x <= z // y+heyting8 :: forall a. Heyting a => a -> Bool+heyting8 _ = neg bottom == top @a && neg top == bottom @a -heytingR4 :: Heyting 'R a => a -> a -> a -> Bool-heytingR4 x y z = (x /\ y) // z == x // y // z+-- Double negation is a monad.+heyting9 :: Heyting a => a -> a -> Bool+heyting9 x y = neg x \/ y <= x // y -heytingR5 :: Heyting 'R a => a -> a -> a -> Bool-heytingR5 x y z = x // (y /\ z) == x // y /\ x // z+heyting10 :: Heyting a => a -> a -> Bool+heyting10 x y = x <= y <=> x // y == top -heytingR6 :: Heyting 'R a => a -> a -> Bool-heytingR6 x y = y <= x // (x /\ y)+heyting11 :: Heyting a => a -> a -> Bool+heyting11 x y = neg (x \/ y) <= neg x -heytingR7 :: Heyting 'R a => a -> a -> Bool-heytingR7 x y = x /\ x // y == x /\ y+heyting12 :: Heyting a => a -> a -> Bool+heyting12 x y = neg (x // y) == neg (neg x) /\ neg y -heytingR8 :: forall a. Heyting 'R a => a -> Bool-heytingR8 _ = neg false == true @a && neg true == false @a+heyting13 :: Heyting a => a -> a -> Bool+heyting13 x y = neg (x \/ y) == neg x /\ neg y --- Double negation is a monad.-heytingR9 :: Heyting 'R a => a -> a -> Bool-heytingR9 x y = neg x \/ y <= x // y+heyting14 :: Heyting a => a -> Bool+heyting14 x = x /\ neg x == bottom -heytingR10 :: Heyting 'R a => a -> a -> Bool-heytingR10 x y = x <= y <=> x // y == true+heyting15 :: Heyting a => a -> Bool+heyting15 x = neg (neg (neg x)) == neg x -heytingR11 :: Heyting 'R a => a -> a -> Bool-heytingR11 x y = neg (x \/ y) <= neg x+heyting16 :: Heyting a => a -> Bool+heyting16 x = neg (neg (x \/ neg x)) == top -heytingR12 :: Heyting 'R a => a -> a -> Bool-heytingR12 x y = neg (x // y) == neg (neg x) /\ neg y+heyting17 :: Heyting a => a -> Bool+heyting17 x = x <= neg (neg x) -heytingR13 :: Heyting 'R a => a -> a -> Bool-heytingR13 x y = neg (x \/ y) == neg x /\ neg y+--+-- x '\\' x           = 'top'+-- x '/\' (x '\\' y)  = x '/\' y+-- y '/\' (x '\\' y)  = y+-- x '\\' (y '\\' z) = (x '/\' y) '\\' z+-- x '\\' (y '/\' z)  = (x '\\' y) '/\' (x '\\' z)+-- 'neg' (x '/\' y)    = 'neg' (x '\/' y)+-- 'neg' (x '\/' y)    = 'neg' x '/\' 'neg' y+-- (x '\\' y) '\/' x '<=' y+-- y '<=' (x '\\' x '/\' y)+-- x '<=' y => (z '\\' x) '<=' (z '\\' y)+-- x '<=' y => (x '\\' z) '<=' (y '\\' z)+-- x '<=' y <=> x '\\' y '==' 'top'+-- x '/\' y '<=' z <=> x '<=' (y '\\' z) <=> y '<=' (x '\\' z)+--+-- -heytingR14 :: Heyting 'R a => a -> Bool-heytingR14 x = x /\ neg x == false+-- adjointL $ ConnL (\x -> y \\ not x) (\z -> not z // not y)+symmetric1 :: Biheyting a => a -> Bool+symmetric1 x = neg x <= non x -heytingR15 :: Heyting 'R a => a -> Bool-heytingR15 x = neg (neg (neg x)) == neg x+symmetric2 :: Symmetric a => a -> Bool+symmetric2 x = (neg . neg) x == (converseR . converseL) x -heytingR16 :: Heyting 'R a => a -> Bool-heytingR16 x = neg (neg (x \/ neg x)) == true+symmetric3 :: Symmetric a => a -> Bool+symmetric3 x = (non . non) x == (converseL . converseR) x -heytingR17 :: Heyting 'R a => a -> Bool-heytingR17 x = x <= neg (neg x)+symmetric4 :: Symmetric a => a -> Bool+symmetric4 x = non x == (converseL . not) x && neg x == (not . converseL) x +symmetric5 :: Symmetric a => a -> Bool+symmetric5 x = non x == (not . converseR) x && neg x == (converseR . not) x++symmetric6 :: Heyting a => a -> Bool+symmetric6 x = neg x \/ neg (neg x) == top++symmetric7 :: Symmetric a => a -> a -> Bool+symmetric7 x y = not (x /\ y) == not x \/ not y++symmetric8 :: Symmetric a => a -> a -> Bool+symmetric8 x y = (not . not) (x \/ y) == not (not x) \/ not (not y)++symmetric9 :: Symmetric a => a -> a -> Bool+symmetric9 x y = not (x \/ y) == not x /\ not y++symmetric10 :: Symmetric a => a -> a -> Bool+symmetric10 x y = converseL (x \/ y) == converseL x \/ converseL y++symmetric11 :: Symmetric a => a -> a -> Bool+symmetric11 x y = converseR (x /\ y) == converseR x /\ converseR y++symmetric12 :: Symmetric a => a -> a -> Bool+symmetric12 x y = converseL (x /\ y) == (non . non) (converseL x /\ converseL y)++symmetric13 :: Symmetric a => a -> a -> Bool+symmetric13 x y = converseR (x \/ y) == (neg . neg) (converseR x \/ converseR y)++boolean0 :: Biheyting a => a -> Bool+boolean0 x = neg x == non x++boolean1 :: Heyting a => a -> Bool+boolean1 x = neg (neg x) == x++boolean2 :: Heyting a => a -> Bool+boolean2 x = x \/ neg x == top++boolean3 :: Coheyting a => a -> Bool+boolean3 x = x /\ non x == bottom++boolean4 :: Heyting a => a -> a -> Bool+boolean4 x y = (x <= y) // (neg y <= neg x)++boolean5 :: Biheyting a => a -> a -> Bool+boolean5 x y = x \\ y == neg (neg y // neg x)++boolean6 :: Biheyting a => a -> a -> Bool+boolean6 x y = x // y == non (non y \\ non x)+ {- infix 4 `joinLe` -- | The partial ordering induced by the join-semilattice structure.@@ -237,8 +271,8 @@  -- | \( \forall a \in R: a \/ a = a \) ----- @ 'idempotent_join' = 'absorbative' 'true' @--- +-- @ 'idempotent_join' = 'absorbative' 'top' @+-- -- See < https:\\en.wikipedia.org/wiki/Band_(mathematics) >. -- -- This is a required property.@@ -254,10 +288,10 @@ -- This is a required property. -- associative_join :: Lattice r => r -> r -> r -> Bool-associative_join = associative_on (~~) (\/) +associative_join = associative_on (~~) (\/)  associative_join_on :: Semilattice 'L r => Rel r b -> r -> r -> r -> b-associative_join_on (=~) = associative_on (=~) (\/) +associative_join_on (=~) = associative_on (=~) (\/)  -- | \( \forall a, b, c: (a \# b) \# c \doteq a \# (b \# c) \) --@@ -272,8 +306,7 @@ commutative_join = commutative_join_on (~~)  commutative_join_on :: Semilattice 'L r => Rel r b -> r -> r -> b-commutative_join_on (=~) = commutative_on (=~) (\/) -+commutative_join_on (=~) = commutative_on (=~) (\/)  -- | \( \forall a, b: a \# b \doteq b \# a \) --@@ -285,7 +318,7 @@ -- Absorbativity is a generalized form of idempotency: -- -- @--- 'absorbative' 'true' a = a \/ a = a+-- 'absorbative' 'top' a = a \/ a = a -- @ -- -- This is a required property.@@ -298,7 +331,7 @@ -- Absorbativity is a generalized form of idempotency: -- -- @--- 'absorbative'' 'false' a = a \/ a = a+-- 'absorbative'' 'bottom' a = a \/ a = a -- @ -- -- This is a required property.@@ -350,7 +383,6 @@ -- See < https:\\en.wikipedia.org/wiki/Distributivity_(order_theory)#Distributivity_for_semilattices > -- modular :: Lattice r => r -> r -> r -> Bool-modular a b c = a \/ (c /\ b) ~~ (a \/ c) /\ b -+modular a b c = a \/ (c /\ b) ~~ (a \/ c) /\ b  -}
src/Data/Order.hs view
@@ -1,60 +1,57 @@-{-# LANGUAGE Safe                       #-}-{-# LANGUAGE PolyKinds                  #-}-{-# LANGUAGE ConstraintKinds            #-}-{-# Language DataKinds                  #-}-{-# LANGUAGE DefaultSignatures          #-}-{-# LANGUAGE DeriveFunctor              #-}-{-# LANGUAGE DeriveGeneric              #-}-{-# LANGUAGE DerivingVia                #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# LANGUAGE StandaloneDeriving         #-}-{-# LANGUAGE TypeOperators              #-}-{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}  module Data.Order (-  -- * Constraint kinds-    Order-  , Total-  -- * Preorders-  , Preorder(..)-  , pcomparing-  -- * DerivingVia-  , Base(..), N5(..) -  -- * Re-exports-  , Ordering(..)-  , Down(..)-  , Positive+    -- * Constraint kinds+    Order,+    Total,++    -- * Preorders+    Preorder (..),+    pcomparing,++    -- * DerivingVia+    Base (..),+    N5 (..),++    -- * Re-exports+    Ordering (..),+    Down (..),+    Positive, ) where  import safe Control.Applicative-import safe Control.Monad.Trans.Select-import safe Control.Monad.Trans.Cont import safe Data.Bool import safe Data.Complex import safe Data.Either-import safe Data.Foldable (foldl')+import safe qualified Data.Eq as Eq import safe Data.Functor.Identity-import safe Data.Functor.Contravariant import safe Data.Int+import safe qualified Data.IntMap as IntMap+import safe qualified Data.IntSet as IntSet import safe Data.List.NonEmpty+import safe qualified Data.Map as Map import safe Data.Maybe-import safe Data.Ord (Down(..))+import safe Data.Ord (Down (..))+import safe qualified Data.Ord as Ord import safe Data.Semigroup-import safe Data.Universe.Class (Finite(..))-import safe Data.Word+import safe qualified Data.Set as Set import safe Data.Void+import safe Data.Word import safe GHC.Real import safe Numeric.Natural-import safe Prelude hiding (Ord(..), Bounded, until)-import safe qualified Data.IntMap as IntMap-import safe qualified Data.IntSet as IntSet-import safe qualified Data.Map as Map-import safe qualified Data.Set as Set-import safe qualified Data.Ord as Ord-import safe qualified Data.Eq as Eq-import safe qualified Data.Finite as F-+import safe Prelude hiding (Bounded, Ord (..), until)  -- | An < https://en.wikipedia.org/wiki/Order_theory#Partially_ordered_sets order > on /a/. --@@ -62,17 +59,15 @@ -- -- We instead use a constraint kind in order to retain compatibility with the -- downstream users of /Eq/.--- type Order a = (Eq.Eq a, Preorder a)  -- | A < https://en.wikipedia.org/wiki/Total_order total order > on /a/.--- --- Note: ideally this would be a subclass of /PartialOrder/, without instances+--+-- Note: ideally this would be a subclass of /Order/, without instances -- for /Float/, /Double/, /Rational/, etc. -- -- We instead use a constraint kind in order to retain compatibility with the -- downstream users of /Ord/.---  type Total a = (Ord.Ord a, Preorder a)  -------------------------------------------------------------------------------@@ -84,7 +79,7 @@ -- A preorder relation '<~' must satisfy the following two axioms: -- -- \( \forall x: x \leq x \) (reflexivity)--- +-- -- \( \forall a, b, c: ((a \leq b) \wedge (b \leq c)) \Rightarrow (a \leq c) \) (transitivity) -- -- Given a preorder on /a/ one may define an equivalence relation '~~' such that@@ -101,25 +96,21 @@ -- -- Minimal complete definition: either 'pcompare' or '<~'. Using 'pcompare' can -- be more efficient for complex types.--- class Preorder a where-    {-# MINIMAL (<~) | pcompare #-} +    {-# MINIMAL (<~) | pcompare #-} -    infix 4 <~, >~, <, >, ?~, ~~, /~, `pcompare`, `pmax`, `pmin`+    infix 4 <~, >~, ?~, ~~, /~, `plt`, `pgt`, `pmax`, `pmin`, `pcompare`      -- | A non-strict preorder order relation on /a/.     --     -- Is /x/ less than or equal to /y/?     ---    -- Is /x/ less than or equal to /y/?-    --     -- '<~' is reflexive, anti-symmetric, and transitive.     --     -- > x <~ y = x < y || x ~~ y     -- > x <~ y = maybe False (<~ EQ) (pcompare x y)     --     -- for all /x/, /y/ in /a/.-    --     (<~) :: a -> a -> Bool     x <~ y = maybe False (Ord.<= EQ) (pcompare x y) @@ -127,79 +118,29 @@     --     -- Is /x/ greater than or equal to /y/?     ---    -- Is /x/ greater than or equal to /y/?-    --     -- '>~' is reflexive, anti-symmetric, and transitive.     --     -- > x >~ y = x > y || x ~~ y     -- > x >~ y = maybe False (>~ EQ) (pcompare x y)     --     -- for all /x/, /y/ in /a/.-    --     (>~) :: a -> a -> Bool     (>~) = flip (<~) -    -- | A strict preorder relation on /a/.-    ---    -- Is /x/ less than /y/?-    ---    -- Is /x/ less than /y/?-    ---    -- '<' is irreflexive, asymmetric, and transitive.-    ---    -- > x < y = x <~ y && not (y <~ x)-    -- > x < y = maybe False (< EQ) (pcompare x y)-    ---    -- When '<~' is antisymmetric then /a/ is a partial -    -- order and we have:-    -- -    -- > x < y = x <~ y && x /~ y-    ---    -- for all /x/, /y/ in /a/.-    ---    (<) :: a -> a -> Bool-    x < y = maybe False (Ord.< EQ) (pcompare x y)--    -- | A converse strict preorder relation on /a/.-    ---    -- Is /x/ greater than /y/?-    ---    -- Is /x/ greater than /y/?-    ---    -- '>' is irreflexive, asymmetric, and transitive.-    ---    -- > x > y = x >~ y && not (y >~ x)-    -- > x > y = maybe False (> EQ) (pcompare x y)-    -- -    -- When '<~' is antisymmetric then /a/ is a partial -    -- order and we have:-    -- -    -- > x > y = x >~ y && x /~ y-    ---    -- for all /x/, /y/ in /a/.-    ---    (>) :: a -> a -> Bool-    (>) = flip (<)--    -- | An equivalence relation on /a/. -    ---    -- Are /x/ and /y/ comparable?+    -- | An equivalence relation on /a/.     --     -- Are /x/ and /y/ comparable?     --     -- '?~' is reflexive, symmetric, and transitive.     --     -- If /a/ implements 'Ord' then we should have @x ?~ y = True@.-    --     (?~) :: a -> a -> Bool     x ?~ y = maybe False (const True) (pcompare x y)-    +     -- | An equivalence relation on /a/.     --     -- Are /x/ and /y/ equivalent?     ---    -- Are /x/ and /y/ equivalent?-    --     -- '~~' is reflexive, symmetric, and transitive.     --     -- > x ~~ y = x <~ y && y <~ x@@ -207,19 +148,53 @@     --     -- Use this as a lawful substitute for '==' when comparing     -- floats, doubles, or rationals.-    --     (~~) :: a -> a -> Bool     x ~~ y = maybe False (Eq.== EQ) (pcompare x y)      -- | Negation of '~~'.     --     -- Are /x/ and /y/ not equivalent?-    --     (/~) :: a -> a -> Bool     x /~ y = not $ x ~~ y-    -    -- | A similarity relation on /a/. ++    -- | A strict preorder relation on /a/.     --+    -- Is /x/ less than /y/?+    --+    -- 'plt' is irreflexive, asymmetric, and transitive.+    --+    -- > x `plt` y = x <~ y && not (y <~ x)+    -- > x `plt` y = maybe False (< EQ) (pcompare x y)+    --+    -- When '<~' is antisymmetric then /a/ is a partial+    -- order and we have:+    --+    -- > x `plt` y = x <~ y && x /~ y+    --+    -- for all /x/, /y/ in /a/.+    plt :: a -> a -> Bool+    plt x y = maybe False (Ord.< EQ) (pcompare x y)++    -- | A converse strict preorder relation on /a/.+    --+    -- Is /x/ greater than /y/?+    --+    -- 'pgt' is irreflexive, asymmetric, and transitive.+    --+    -- > x `pgt` y = x >~ y && not (y >~ x)+    -- > x `pgt` y = maybe False (> EQ) (pcompare x y)+    --+    -- When '<~' is antisymmetric then /a/ is a partial+    -- order and we have:+    --+    -- > x `pgt` y = x >~ y && x /~ y+    --+    -- for all /x/, /y/ in /a/.+    pgt :: a -> a -> Bool+    pgt = flip plt++    -- | A similarity relation on /a/.+    --     -- Are /x/ and /y/ either equivalent or incomparable?     --     -- 'similar' is reflexive and symmetric, but not necessarily transitive.@@ -229,10 +204,31 @@     -- > similar (0/0 :: Float) 5 = True     --     -- If /a/ implements 'Ord' then we should have @('~~') = 'similar' = ('==')@.-    --     similar :: a -> a -> Bool     similar x y = maybe True (Eq.== EQ) (pcompare x y) +    -- | A partial version of 'Data.Ord.max'.+    --+    -- Returns the left-hand argument in the case of equality.+    pmax :: a -> a -> Maybe a+    pmax x y = do+        o <- pcompare x y+        case o of+            GT -> Just x+            EQ -> Just x+            LT -> Just y++    -- | A partial version of 'Data.Ord.min'.+    --+    -- Returns the left-hand argument in the case of equality.+    pmin :: a -> a -> Maybe a+    pmin x y = do+        o <- pcompare x y+        case o of+            GT -> Just y+            EQ -> Just x+            LT -> Just x+     -- | A partial version of 'Data.Ord.compare'.     --     -- > x <  y = maybe False (<  EQ) $ pcompare x y@@ -242,46 +238,20 @@     -- > x ~~ y = maybe False (~~ EQ) $ pcompare x y     -- > x ?~ y = maybe False (const True) $ pcompare x y     -- > similar x y = maybe True (~~ EQ) $ pcompare x y-    -- -    -- If /a/ implements 'Ord' then we should have @'pcompare' x y = 'Just' '$' 'compare' x y@.     --+    -- If /a/ implements 'Ord' then we should have @'pcompare' x y = 'Just' '$' 'compare' x y@.     pcompare :: a -> a -> Maybe Ordering-    pcompare x y -      | x <~ y    = Just $ if y <~ x then EQ else LT-      | y <~ x    = Just GT-      | otherwise = Nothing--    -- | A partial version of 'Data.Ord.max'. -    ---    -- Returns the left-hand argument in the case of equality.-    ---    pmax :: a -> a -> Maybe a-    pmax x y = do-      o <- pcompare x y-      case o of-        GT -> Just x-        EQ -> Just x-        LT -> Just y--    -- | A partial version of 'Data.Ord.min'. -    ---    -- Returns the left-hand argument in the case of equality.-    ---    pmin :: a -> a -> Maybe a-    pmin x y = do-      o <- pcompare x y-      case o of-        GT -> Just y-        EQ -> Just x-        LT -> Just x+    pcompare x y+        | x <~ y = Just $ if y <~ x then EQ else LT+        | y <~ x = Just GT+        | otherwise = Nothing  -- | A partial version of 'Data.Order.Total.comparing'. -- -- > pcomparing p x y = pcompare (p x) (p y) ----- The partial application /pcomparing f/ induces a lawful preorder for +-- The partial application /pcomparing f/ induces a lawful preorder for -- any total function /f/.--- pcomparing :: Preorder a => (b -> a) -> b -> b -> Maybe Ordering pcomparing p x y = pcompare (p x) (p y) @@ -289,14 +259,14 @@ -- DerivingVia --------------------------------------------------------------------- -newtype Base a = Base { getBase :: a } deriving stock (Eq.Eq, Ord.Ord, Show, Functor)-  deriving Applicative via Identity-+newtype Base a = Base {getBase :: a}+    deriving stock (Eq.Eq, Ord.Ord, Show, Functor)+    deriving (Applicative) via Identity  instance Ord.Ord a => Preorder (Base a) where-  x <~ y = getBase $ liftA2 (Ord.<=) x y-  x >~ y = getBase $ liftA2 (Ord.>=) x y-  pcompare x y = Just . getBase $ liftA2 Ord.compare x y+    x <~ y = getBase $ liftA2 (Ord.<=) x y+    x >~ y = getBase $ liftA2 (Ord.>=) x y+    pcompare x y = Just . getBase $ liftA2 Ord.compare x y  --instance Preorder Void where  _ <~ _ = True deriving via (Base Void) instance Preorder Void@@ -316,32 +286,30 @@ deriving via (Base Int32) instance Preorder Int32 deriving via (Base Int64) instance Preorder Int64 deriving via (Base Integer) instance Preorder Integer-deriving via (Base (F.Finite n)) instance Preorder (F.Finite n)  --TODO move to Order and derive Preorder as well-newtype N5 a = N5 { getN5 :: a } deriving stock (Eq, Show, Functor)-  deriving Applicative via Identity+newtype N5 a = N5 {getN5 :: a}+    deriving stock (Eq, Show, Functor)+    deriving (Applicative) via Identity  instance (Ord.Ord a, Fractional a) => Preorder (N5 a) where-  x <~ y = getN5 $ liftA2 n5Le x y+    x <~ y = getN5 $ liftA2 n5Le x y  -- N5 lattice ordering: NInf <= NaN <= PInf n5Le :: (Ord.Ord a, Fractional a) => a -> a -> Bool-n5Le x y | x Eq./= x && y Eq./= y = True-       | x Eq./= x = y == 1/0-       | y Eq./= y = x == -1/0-       | otherwise = x Ord.<= y+n5Le x y+    | x Eq./= x && y Eq./= y = True+    | x Eq./= x = y == 1 / 0+    | y Eq./= y = x == -1 / 0+    | otherwise = x Ord.<= y  deriving via (N5 Float) instance Preorder Float deriving via (N5 Double) instance Preorder Double - --------------------------------------------------------------------- -- Instances --------------------------------------------------------------------- -- -- N5 lattice ordering: NInf <= NaN <= PInf {- pinf = 1 :% 0@@ -358,206 +326,111 @@ Nothing -} pcompareRat :: Rational -> Rational -> Maybe Ordering-pcompareRat (0:%0) (x:%0) = Just $ Ord.compare 0 x-pcompareRat (x:%0) (0:%0) = Just $ Ord.compare x 0-pcompareRat (x:%0) (y:%0) = Just $ Ord.compare (signum x) (signum y)-pcompareRat (0:%0) _ = Nothing-pcompareRat _ (0:%0) = Nothing-pcompareRat _ (x:%0) = Just $ Ord.compare 0 x -- guard against div-by-zero exceptions-pcompareRat (x:%0) _ = Just $ Ord.compare x 0+pcompareRat (0 :% 0) (x :% 0) = Just $ Ord.compare 0 x+pcompareRat (x :% 0) (0 :% 0) = Just $ Ord.compare x 0+pcompareRat (x :% 0) (y :% 0) = Just $ Ord.compare (signum x) (signum y)+pcompareRat (0 :% 0) _ = Nothing+pcompareRat _ (0 :% 0) = Nothing+pcompareRat _ (x :% 0) = Just $ Ord.compare 0 x -- guard against div-by-zero exceptions+pcompareRat (x :% 0) _ = Just $ Ord.compare x 0 pcompareRat x y = Just $ Ord.compare x y  -- | Positive rationals, extended with an absorbing zero. -- -- 'Positive' is the canonical < https://en.wikipedia.org/wiki/Semifield#Examples semifield >.--- type Positive = Ratio Natural  -- N5 lattice comparison pcomparePos :: Positive -> Positive -> Maybe Ordering-pcomparePos (0:%0) (x:%0) = Just $ Ord.compare 0 x-pcomparePos (x:%0) (0:%0) = Just $ Ord.compare x 0-pcomparePos (_:%0) (_:%0) = Just EQ -- all non-nan infs are equal-pcomparePos (0:%0) (0:%_) = Just $ GT-pcomparePos (0:%_) (0:%0) = Just $ LT-pcomparePos (0:%0) _ = Nothing-pcomparePos _ (0:%0) = Nothing-pcomparePos (x:%y) (x':%y') = Just $ Ord.compare (x*y') (x'*y)+pcomparePos (0 :% 0) (x :% 0) = Just $ Ord.compare 0 x+pcomparePos (x :% 0) (0 :% 0) = Just $ Ord.compare x 0+pcomparePos (_ :% 0) (_ :% 0) = Just EQ -- all non-nan infs are equal+pcomparePos (0 :% 0) (0 :% _) = Just $ GT+pcomparePos (0 :% _) (0 :% 0) = Just $ LT+pcomparePos (0 :% 0) _ = Nothing+pcomparePos _ (0 :% 0) = Nothing+pcomparePos (x :% y) (x' :% y') = Just $ Ord.compare (x * y') (x' * y)  instance Preorder Rational where-  pcompare = pcompareRat+    pcompare = pcompareRat  instance Preorder Positive where-  pcompare = pcomparePos+    pcompare = pcomparePos  instance (Preorder a, Num a) => Preorder (Complex a) where-  pcompare = pcomparing $ \(x :+ y) -> x^2 + y^2+    pcompare = pcomparing $ \(x :+ y) -> x * x + y * y  instance Preorder a => Preorder (Down a) where-  (Down x) <~ (Down y) = y <~ x-  pcompare (Down x) (Down y) = pcompare y x+    (Down x) <~ (Down y) = y <~ x+    pcompare (Down x) (Down y) = pcompare y x  instance Preorder a => Preorder (Dual a) where-  (Dual x) <~ (Dual y) = y <~ x-  pcompare (Dual x) (Dual y) = pcompare y x+    (Dual x) <~ (Dual y) = y <~ x+    pcompare (Dual x) (Dual y) = pcompare y x  instance Preorder a => Preorder (Max a) where-  Max a <~ Max b = a <~ b+    Max a <~ Max b = a <~ b  instance Preorder a => Preorder (Min a) where-  Min a <~ Min b = a <~ b+    Min a <~ Min b = a <~ b  instance Preorder Any where-  Any x <~ Any y = x <~ y+    Any x <~ Any y = x <~ y  instance Preorder All where-  All x <~ All y = y <~ x+    All x <~ All y = y <~ x  instance Preorder a => Preorder (Identity a) where-  pcompare (Identity x) (Identity y) = pcompare x y+    pcompare (Identity x) (Identity y) = pcompare x y  instance Preorder a => Preorder (Maybe a) where-  Nothing <~ _ = True-  Just{} <~ Nothing = False-  Just a <~ Just b = a <~ b+    Nothing <~ _ = True+    Just{} <~ Nothing = False+    Just a <~ Just b = a <~ b  instance Preorder a => Preorder [a] where-  {-# SPECIALISE instance Preorder [Char] #-}-  --[] <~ _     = True-  --(_:_) <~ [] = False-  --(x:xs) <~ (y:ys) = x <~ y && xs <~ ys+    {-# SPECIALIZE instance Preorder [Char] #-} -  pcompare []     []     = Just EQ-  pcompare []     (_:_)  = Just LT-  pcompare (_:_)  []     = Just GT-  pcompare (x:xs) (y:ys) = case pcompare x y of-                              Just EQ -> pcompare xs ys-                              other   -> other+    --[] <~ _     = True+    --(_:_) <~ [] = False+    --(x:xs) <~ (y:ys) = x <~ y && xs <~ ys +    pcompare [] [] = Just EQ+    pcompare [] (_ : _) = Just LT+    pcompare (_ : _) [] = Just GT+    pcompare (x : xs) (y : ys) = case pcompare x y of+        Just EQ -> pcompare xs ys+        other -> other+ instance Preorder a => Preorder (NonEmpty a) where-  (x :| xs) <~ (y :| ys) = x <~ y && xs <~ ys+    (x :| xs) <~ (y :| ys) = x <~ y && xs <~ ys  instance (Preorder a, Preorder b) => Preorder (Either a b) where-  Right a <~ Right b  = a <~ b-  Right _ <~ _        = False--  Left a <~ Left b   = a <~ b-  Left _ <~ _        = True- -instance (Preorder a, Preorder b) => Preorder (a, b) where -  (a,b) <~ (i,j) = a <~ i && b <~ j+    Right a <~ Right b = a <~ b+    Right _ <~ _ = False+    Left a <~ Left b = a <~ b+    Left _ <~ _ = True -instance (Preorder a, Preorder b, Preorder c) => Preorder (a, b, c) where -  (a,b,c) <~ (i,j,k) = a <~ i && b <~ j && c <~ k+instance (Preorder a, Preorder b) => Preorder (a, b) where+    (a, b) <~ (i, j) = a <~ i && b <~ j -instance (Preorder a, Preorder b, Preorder c, Preorder d) => Preorder (a, b, c, d) where -  (a,b,c,d) <~ (i,j,k,l) = a <~ i && b <~ j && c <~ k && d <~ l+instance (Preorder a, Preorder b, Preorder c) => Preorder (a, b, c) where+    (a, b, c) <~ (i, j, k) = a <~ i && b <~ j && c <~ k -instance (Preorder a, Preorder b, Preorder c, Preorder d, Preorder e) => Preorder (a, b, c, d, e) where -  (a,b,c,d,e) <~ (i,j,k,l,m) = a <~ i && b <~ j && c <~ k && d <~ l && e <~ m+instance (Preorder a, Preorder b, Preorder c, Preorder d) => Preorder (a, b, c, d) where+    (a, b, c, d) <~ (i, j, k, l) = a <~ i && b <~ j && c <~ k && d <~ l ---instance (Foldable1 f, Representable f, Preorder a) => Preorder (Co f a) where---  Co f <~ Co g = and $ liftR2 (<~) f g+instance (Preorder a, Preorder b, Preorder c, Preorder d, Preorder e) => Preorder (a, b, c, d, e) where+    (a, b, c, d, e) <~ (i, j, k, l, m) = a <~ i && b <~ j && c <~ k && d <~ l && e <~ m  instance (Ord.Ord k, Preorder a) => Preorder (Map.Map k a) where-  (<~) = Map.isSubmapOfBy (<~)+    (<~) = Map.isSubmapOfBy (<~)  instance Ord.Ord a => Preorder (Set.Set a) where-  (<~) = Set.isSubsetOf+    (<~) = Set.isSubsetOf  instance Preorder a => Preorder (IntMap.IntMap a) where-  (<~) = IntMap.isSubmapOfBy (<~)+    (<~) = IntMap.isSubmapOfBy (<~)  instance Preorder IntSet.IntSet where-  (<~) = IntSet.isSubsetOf---- | TODO: short-circuiting version.------ >>> const 3 <~ (const 4 :: Int8 -> Int8)--- True--- >>> const 3 <~ (id :: Int8 -> Int8)--- False-instance (Finite a, Preorder b) => Preorder (a -> b) where-  pcompare f g = foldl' acc (Just EQ) [f x `pcompare` g x | x <- universeF]-    where acc old new = do-            m' <- new-            n' <- old-            case (m', n') of-              (x , EQ) -> Just x-              (EQ, y ) -> Just y-              (x , y ) -> if x == y then Just x else Nothing--instance (Finite a, Preorder a) => Preorder (Endo a) where-  pcompare (Endo f) (Endo g) = pcompare f g--instance (Finite a, Preorder b) => Preorder (Op b a) where-  --universe = coerce (universe :: [b -> a])-  --universe = map Op universe-  pcompare (Op f) (Op g) = pcompare f g--instance (Finite a) => Preorder (Predicate a) where-  --universe = map (Predicate . flip S.member) universe-  --universe = map Op universe-  pcompare (Predicate f) (Predicate g) = pcompare f g---- |--- >>> cont ($ 1) == (cont ($ 2) :: Cont Bool Int8)--- False--- >>> cont ($ 1) == (cont ($ 2) :: Cont () Int8)--- True-instance (Total a, Preorder r, Finite r) => Preorder (Cont r a) where-  (ContT x) <~ (ContT y) = x `contLe` y--instance (Total a, Preorder r, Finite r) => Preorder (Select r a) where-  (SelectT x) <~ (SelectT y) = x `contLe` y--contLe :: forall a b c. (Finite b, Ord.Ord a, Preorder a, Preorder b, Preorder c) => ((a -> b) -> c) -> ((a -> b) -> c) -> Bool-contLe x y = if (universeF :: [b]) ~~ [] then True else point $ counter Map.empty-  where-    --point :: Preorder b => a -> Bool-    point ar = x ar <~ y ar--    --counter :: (Finite b, Ord.Ord a, Preorder c) => Map.Map a b -> a -> b-    counter acc a = case Map.lookup a acc of-      Just b -> b--      Nothing -> case [b | b <- universeF -                         , let acc' = Map.insert a b acc-                               func a' | a' < a = counter acc a'-                                 | otherwise = counter acc' a'-                         , not . point $ func-                      ] of-                   (b:_) -> b-                   [] -> Prelude.head universeF -- Return a failed counter-example to be pruned by 'point'---{--exm1, exm2, exm3 :: Cont Bool Integer-exm1 = cont $ \ib -> (ib 7 && ib 4) || ib 8-exm2 = cont $ \ib -> (ib 7 || ib 8) && (ib 4 || ib 8)-exm3 = cont $ \ib -> (ib 7 || ib 8) && ib 4---- exm1 ~~ exm2 >~ exm3-ex1 = (exm1 ~~ exm2, exm1 ~~ exm3, exm2 ~~ exm3) --(True, False, False)-ex2 = (exm1 ~~ exm2, exm1 >~ exm3, exm2 >~ exm3) --(True, True, True)-ex3 = (exm1 ~~ exm2 \/ exm3) -- True---- exm2 >~ exm3--- λ> runCont exm2 diff--- True--- λ> runCont exm3 diff--- False-diff :: Integer -> Bool-diff i = if i ~~ 7 || i ~~ 8 then True else False--}-------------------------------------------------------------------------- Orphan Instances------------------------------------------------------------------------instance (Finite a, Eq b) => Eq (a -> b) where-  f == g = and [f x == g x | x <- universeF]--deriving via (a -> a) instance (Finite a, Eq a) => Eq (Endo a)-deriving via (a -> b) instance (Finite a, Eq b) => Eq (Op b a)-deriving via (Op Bool a) instance (Finite a) => Eq (Predicate a)+    (<~) = IntSet.isSubsetOf
src/Data/Order/Extended.hs view
@@ -1,25 +1,26 @@-{-# Language Safe                #-}-{-# Language DeriveFunctor       #-}-{-# Language DeriveGeneric       #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE Safe #-}  module Data.Order.Extended (-  -- * Lattice extensions-    type Lifted-  , type Lowered-  , Extended(..)-  , extended-  --, retract-  -- * Lattice Extensions-  , liftMaybe-  , liftEitherL-  , liftEitherR-  , liftExtended+    -- * Lattice extensions+    Lifted,+    Lowered,+    Extended (..),+    extended,+    --, retract++    -- * Lattice Extensions+    liftMaybe,+    liftEitherL,+    liftEitherR,+    liftExtended, ) where  import safe Data.Order import safe Data.Order.Syntax import safe GHC.Generics-import safe Prelude hiding (Eq(..), Ord(..),Bounded)+import safe Prelude hiding (Bounded, Eq (..), Ord (..))  type Lifted = Either () @@ -29,21 +30,19 @@ -- -- The top is the absorbing element for the join, and the bottom is the absorbing -- element for the meet.--- data Extended a = Bottom | Extended a | Top-  deriving ( Eq, Ord, Show, Generic, Functor, Generic1 )+    deriving (Eq, Ord, Show, Generic, Functor, Generic1)  -- | Eliminate an 'Extended'. extended :: b -> b -> (a -> b) -> Extended a -> b-extended b _ _ Bottom       = b-extended _ t _ Top          = t+extended b _ _ Bottom = b+extended _ t _ Top = t extended _ _ f (Extended x) = f x  ------------------------------------------------------------------------------- -- Lattice extensions ------------------------------------------------------------------------------- - {- lifts :: Minimal a => Eq a => (a -> b) -> a -> Lifted b lifts = liftEitherL (== minimal)@@ -55,40 +54,48 @@ lowered f = either f (const maximal)  lowers :: Maximal a => Eq a => (a -> b) -> a -> Lowered b-lowers = liftEitherR (== maximal) +lowers = liftEitherR (== maximal) -}  liftMaybe :: (a -> Bool) -> (a -> b) -> a -> Maybe b-liftMaybe p f = g where-  g i | p i = Nothing-      | otherwise = Just $ f i+liftMaybe p f = g+  where+    g i+        | p i = Nothing+        | otherwise = Just $ f i  liftEitherL :: (a -> Bool) -> (a -> b) -> a -> Lifted b-liftEitherL p f = g where-  g i | p i = Left ()-      | otherwise = Right $ f i+liftEitherL p f = g+  where+    g i+        | p i = Left ()+        | otherwise = Right $ f i  liftEitherR :: (a -> Bool) -> (a -> b) -> a -> Lowered b-liftEitherR p f = g where-  g i | p i = Right ()-      | otherwise = Left $ f i+liftEitherR p f = g+  where+    g i+        | p i = Right ()+        | otherwise = Left $ f i  liftExtended :: (a -> Bool) -> (a -> Bool) -> (a -> b) -> a -> Extended b-liftExtended p q f = g where-  g i | p i = Bottom-      | q i = Top-      | otherwise = Extended $ f i+liftExtended p q f = g+  where+    g i+        | p i = Bottom+        | q i = Top+        | otherwise = Extended $ f i  --------------------------------------------------------------------- -- Instances ---------------------------------------------------------------------  instance Preorder a => Preorder (Extended a) where-  _ <~ Top = True-  Top <~ _ = False-  Bottom <~ _ = True-  _ <~ Bottom = False-  Extended x <~ Extended y = x <~ y+    _ <~ Top = True+    Top <~ _ = False+    Bottom <~ _ = True+    _ <~ Bottom = False+    Extended x <~ Extended y = x <~ y  {- instance Universe a => Universe (Extended a) where
src/Data/Order/Interval.hs view
@@ -1,33 +1,21 @@-{-# LANGUAGE DeriveFunctor              #-}-{-# LANGUAGE Safe              #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE Safe #-}  module Data.Order.Interval (-    Interval()-  , imap-  , (...)-  , iempty-  , singleton-  , contains-  , endpts-  --, above-  --, below-  --, interval-  -- * Floating point intervals-  , open32-  , open32L-  , open32R-  , open64-  , open64L-  , open64R+    Interval (),+    imap,+    (...),+    iempty,+    singleton,+    contains,+    endpts, ) where  import safe Data.Bifunctor (bimap)+import safe qualified Data.Eq as Eq import safe Data.Order import safe Data.Order.Syntax-import safe Prelude hiding (Ord(..), Eq(..), Bounded, until)-import safe qualified Data.Eq as Eq-import safe qualified Data.Connection.Float as F32-import safe qualified Data.Connection.Double as F64+import safe Prelude hiding (Bounded, Eq (..), Ord (..), until)  --------------------------------------------------------------------- -- Intervals@@ -38,14 +26,12 @@ -- An interval in a poset /P/ is a subset /I/ of /P/ with the following property: -- -- \( \forall x, y \in I, z \in P: x \leq z \leq y \Rightarrow z \in I \)----data Interval a = Empty | Interval !a !a deriving Show+data Interval a = Empty | Interval !a !a deriving (Show)  -- | Map over an interval. -- -- /Note/ this is not a functor, as a non-monotonic map -- may cause the interval to collapse to the iempty interval.--- imap :: Preorder b => (a -> b) -> Interval a -> Interval b imap f = maybe iempty (uncurry (...)) . fmap (bimap f f) . endpts @@ -55,19 +41,17 @@ -- -- /Note/: Endpoints are preorder-sorted. If /pcompare x y = Nothing/ -- then the resulting interval will be empty.---  (...) :: Preorder a => a -> a -> Interval a x ... y = case pcompare x y of-  Just LT -> Interval x y-  Just EQ -> Interval x y-  _ -> Empty+    Just LT -> Interval x y+    Just EQ -> Interval x y+    _ -> Empty {-# INLINE (...) #-}  -- | The iempty interval. -- -- >>> iempty -- Empty--- iempty :: Interval a iempty = Empty {-# INLINE iempty #-}@@ -76,13 +60,11 @@ -- -- >>> singleton 1 -- 1 ... 1--- singleton :: a -> Interval a singleton a = Interval a a {-# INLINE singleton #-}  -- | Obtain the endpoints of an interval.--- endpts :: Interval a -> Maybe (a, a) endpts Empty = Nothing endpts (Interval x y) = Just (x, y)@@ -92,132 +74,21 @@ contains Empty _ = False contains (Interval x y) p = x <~ p && p <~ y -{------ | \( X_\geq(x) = \{ y \in X | y \geq x \} \)------ Construct the upper set of an element /x/.------ This function is monotone:------ > x <~ y <=> above x <~ above y------ by the Yoneda lemma for preorders.----above :: Maximal a => a -> Interval a-above x = x ... maximal-{-# INLINE above #-}---- | \( X_\leq(x) = \{ y \in X | y \leq x \} \)------ Construct the lower set of an element /x/.------ This function is antitone:------ > x <~ y <=> below x >~ below y----below :: Minimal a => a -> Interval a-below x = minimal ... x-{-# INLINE below #-}----}- ------------------------------------------------------------------------ Floating point intervals--------------------------------------------------------------------------- | Construnct an open interval.------ >>> contains 1 $ open32 1 2--- False--- >>> contains 2 $ open32 1 2--- False----open32 :: Float -> Float -> Interval Float-open32 x y = F32.shift 1 x ... F32.shift (-1) y---- | Construnct a half-open interval.------ >>> contains 1 $ open32L 1 2--- False--- >>> contains 2 $ open32L 1 2--- True----open32L :: Float -> Float -> Interval Float-open32L x y = F32.shift 1 x ... y---- | Construnct a half-open interval.------ >>> contains 1 $ open32R 1 2--- True--- >>> contains 2 $ open32R 1 2--- False----open32R :: Float -> Float -> Interval Float-open32R x y = x ... F32.shift (-1) y---- | Construnct an open interval.------ >>> contains 1 $ open64 1 2--- False--- >>> contains 2 $ open64 1 2--- False----open64 :: Double -> Double -> Interval Double-open64 x y = F64.shift 1 x ... F64.shift (-1) y---- | Construnct a half-open interval.------ >>> contains 1 $ open64L 1 2--- False--- >>> contains 2 $ open64L 1 2--- True----open64L :: Double -> Double -> Interval Double-open64L x y = F64.shift 1 x ... y---- | Construnct a half-open interval.------ >>> contains 1 $ open64R 1 2--- True--- >>> contains 2 $ open64R 1 2--- False----open64R :: Double -> Double -> Interval Double-open64R x y = x ... F64.shift (-1) y--{---- | Generate a list of the contents on an interval.------ Returns the list of values in the interval defined by a bounding pair.------ Lawful variant of 'enumFromTo'.----indexFromTo :: Interval Float -> [Float]-indexFromTo i = case endpts i of-  Nothing -> []-  Just (x, y) -> flip unfoldr x $ \i -> if i ~~ y then Nothing else Just (i, shift 1 i)--}----------------------------------------------------------------------- -- Instances ---------------------------------------------------------------------  instance Eq a => Eq (Interval a) where-  Empty == Empty = True-  Empty == _ = False-  _ == Empty = False-  Interval x y == Interval x' y' = x == x' && y == y'+    Empty == Empty = True+    Empty == _ = False+    _ == Empty = False+    Interval x y == Interval x' y' = x == x' && y == y'  -- | A < https://en.wikipedia.org/wiki/Containment_order containment order >--- instance Preorder a => Preorder (Interval a) where-  Empty <~ _ = True-  _ <~ Empty = False-  Interval x y <~ Interval x' y' = x' <~ x && y <~ y'+    Empty <~ _ = True+    _ <~ Empty = False+    Interval x y <~ Interval x' y' = x' <~ x && y <~ y'  {- instance Bounded 'L a => Connection k (Maybe a) (Interval a) where@@ -231,19 +102,15 @@     f = maybe Nothing (Just . uncurry (\/)) . endpts     g = maybe iempty singleton     h = maybe Nothing (Just . uncurry (/\)) . endpts--} --{- instance Lattice a => Lattice (Interval a) where   (\/) = joinInterval   (/\) = meetInterval +bottom = Empty+top = bottom ... top joinInterval Empty i = i joinInterval i Empty = i joinInterval (I x y) (I x' y') = I (x /\ x') (y \/ y') -instance Bounded a => Bounded (Interval a) where-  bottom = Empty-  top = bottom ... top -}
src/Data/Order/Property.hs view
@@ -1,57 +1,65 @@-{-# LANGUAGE DataKinds                  #-}+{-# LANGUAGE DataKinds #-}+ -- | See <https://en.wikipedia.org/wiki/Binary_relation#Properties>. module Data.Order.Property (-    type Rel-  , (==>), (<=>)-  , xor, xor3-  -- * Orders-  , preorder-  , order-  -- ** Non-strict preorders-  , antisymmetric_le-  , reflexive_le-  , transitive_le-  , connex_le-  -- ** Strict preorders-  , asymmetric_lt-  , transitive_lt-  , irreflexive_lt-  , semiconnex_lt-  , trichotomous_lt-  -- ** Semiorders-  , chain_22-  , chain_31-  -- * Equivalence relations-  , symmetric_eq-  , reflexive_eq-  , transitive_eq-  -- * Properties of generic relations-  , reflexive-  , irreflexive-  , coreflexive-  , quasireflexive-  , transitive-  , euclideanL-  , euclideanR-  , connex-  , semiconnex-  , trichotomous-  , symmetric-  , asymmetric-  , antisymmetric+    Rel,+    (==>),+    (<=>),+    xor,+    xor3,++    -- * Orders+    preorder,+    order,++    -- ** Non-strict preorders+    antisymmetric_le,+    reflexive_le,+    transitive_le,+    connex_le,++    -- ** Strict preorders+    asymmetric_lt,+    transitive_lt,+    irreflexive_lt,+    semiconnex_lt,+    trichotomous_lt,++    -- ** Semiorders+    chain_22,+    chain_31,++    -- * Equivalence relations+    symmetric_eq,+    reflexive_eq,+    transitive_eq,++    -- * Properties of generic relations+    reflexive,+    irreflexive,+    coreflexive,+    quasireflexive,+    transitive,+    euclideanL,+    euclideanR,+    connex,+    semiconnex,+    trichotomous,+    symmetric,+    asymmetric,+    antisymmetric, ) where -import Data.Connection.Conn+import Data.Lattice hiding (not) import Data.Order import Data.Order.Syntax-import Data.Lattice hiding (not)-import Prelude hiding (Ord(..), Eq(..))+import Prelude hiding (Eq (..), Ord (..))  -- | See <https://en.wikipedia.org/wiki/Binary_relation#Properties>. -- -- Note that these properties do not exhaust all of the possibilities. ----- As an example over the natural numbers, the relation \(a \# b \) defined by +-- As an example over the natural numbers, the relation \(a \# b \) defined by -- \( a > 2 \) is neither symmetric nor antisymmetric, let alone asymmetric. type Rel r b = r -> r -> b @@ -65,38 +73,34 @@ (<=>) :: Bool -> Bool -> Bool (<=>) x y = (x ==> y) && (y ==> x) -- xor3 :: Bool -> Bool -> Bool -> Bool xor3 a b c = (a `xor` (b `xor` c)) && not (a && b && c)  -- | Check a 'Preorder' is internally consistent. -- -- This is a required property.--- preorder :: Preorder r => r -> r -> Bool-preorder x y = -  ((x <~ y) == le x y) &&-  ((x >~ y) == ge x y) &&-  ((x ?~ y) == cp x y) &&-  ((x ~~ y) == eq x y) &&-  ((x /~ y) == ne x y) &&-  ((x <  y) == lt x y) &&-  ((x >  y) == gt x y) &&-  (similar x y == sm x y) &&-  (pcompare x y == pcmp x y)-+preorder x y =+    ((x <~ y) == le x y)+        && ((x >~ y) == ge x y)+        && ((x ?~ y) == cp x y)+        && ((x ~~ y) == eq x y)+        && ((x /~ y) == ne x y)+        && ((x < y) == lt x y)+        && ((x > y) == gt x y)+        && (similar x y == sm x y)+        && (pcompare x y == pcmp x y)   where     le x1 y1 = x1 < y1 || x1 ~~ y1      ge = flip le-    +     cp x1 y1 = x1 <~ y1 || x1 >~ y1      eq x1 y1 = x1 <~ y1 && x1 >~ y1      ne x1 y1 = not $ eq x1 y1-    +     lt x1 y1 = x1 <~ y1 && x1 /~ y1      gt = flip lt@@ -104,22 +108,19 @@     sm x1 y1 = not (x1 < y1) && not (x1 > y1)      pcmp x1 y1-      | x1 <~ y1 = Just $ if y1 <~ x1 then EQ else LT-      | y1 <~ x1 = Just GT-      | otherwise = Nothing-+        | x1 <~ y1 = Just $ if y1 <~ x1 then EQ else LT+        | y1 <~ x1 = Just GT+        | otherwise = Nothing  -- | Check that an 'Order' is internally consistent. -- -- This is a required property.--- order :: Order r => r -> r -> Bool-order x y = -  ((x <= y) == le x y) &&-  ((x >= y) == ge x y) &&-  ((x == y) == eq x y) &&-  ((x /= y) == ne x y)-+order x y =+    ((x <= y) == le x y)+        && ((x >= y) == ge x y)+        && ((x == y) == eq x y)+        && ((x /= y) == ne x y)   where     le x1 y1 = maybe False (<~ EQ) $ pcompare x1 y1 @@ -138,7 +139,6 @@ -- '<~' is an antisymmetric relation. -- -- This is a required property.--- antisymmetric_le :: Preorder r => r -> r -> Bool antisymmetric_le = antisymmetric (~~) (<~) @@ -147,23 +147,20 @@ -- '<~' is a reflexive relation. -- -- This is a required property.----reflexive_le :: Preorder r => r ->  Bool-reflexive_le = reflexive (<~) +reflexive_le :: Preorder r => r -> Bool+reflexive_le = reflexive (<~)  -- | \( \forall a, b, c: ((a \leq b) \wedge (b \leq c)) \Rightarrow (a \leq c) \) -- -- '<~' is an transitive relation. -- -- This is a required property.--- transitive_le :: Preorder r => r -> r -> r -> Bool transitive_le = transitive (<~)  -- | \( \forall a, b: ((a \leq b) \vee (b \leq a)) \) -- -- '<~' is a connex relation.---  connex_le :: Preorder r => r -> r -> Bool connex_le = connex (<~) @@ -176,7 +173,6 @@ -- 'lt' is an asymmetric relation. -- -- This is a required property.--- asymmetric_lt :: Preorder r => r -> r -> Bool asymmetric_lt = asymmetric (<) @@ -185,23 +181,20 @@ -- 'lt' is an irreflexive relation. -- -- This is a required property.----irreflexive_lt :: Preorder r => r ->  Bool-irreflexive_lt = irreflexive (<) +irreflexive_lt :: Preorder r => r -> Bool+irreflexive_lt = irreflexive (<)  -- | \( \forall a, b, c: ((a \lt b) \wedge (b \lt c)) \Rightarrow (a \lt c) \) -- -- 'lt' is a transitive relation. -- -- This is a required property.--- transitive_lt :: Preorder r => r -> r -> r -> Bool transitive_lt = transitive (<)  -- | \( \forall a, b: \neg (a = b) \Rightarrow ((a \lt b) \vee (b \lt a)) \) -- -- 'lt' is a semiconnex relation.--- semiconnex_lt :: Preorder r => r -> r -> Bool semiconnex_lt = semiconnex (~~) (<) @@ -210,7 +203,6 @@ -- In other words, exactly one of \(a \lt b\), \(a = b\), or \(b \lt a\) holds. -- -- If 'lt' is a trichotomous relation then the set is totally ordered.--- trichotomous_lt :: Preorder r => r -> r -> Bool trichotomous_lt = trichotomous (~~) (<) @@ -218,10 +210,9 @@ -- Semiorders --------------------------------------------------------------------- --- | \( \forall x, y, z, w: x \lt y \wedge y \sim z \wedge z \lt w \Rightarrow x \lt w \) +-- | \( \forall x, y, z, w: x \lt y \wedge y \sim z \wedge z \lt w \Rightarrow x \lt w \) -- -- A < https://en.wikipedia.org/wiki/Semiorder semiorder > does not allow 2-2 chains.--- chain_22 :: Preorder r => r -> r -> r -> r -> Bool chain_22 x y z w = x < y && similar y z && z < w ==> x < w @@ -229,7 +220,7 @@ -- -- A < https://en.wikipedia.org/wiki/Semiorder semiorder > does not allow 3-1 chains. ----- /Note/: This library models floats, doubles, rationals etc +-- /Note/: This library models floats, doubles, rationals etc -- as < https://en.wikipedia.org/wiki/Modular_lattice#Examples N5 > lattices, -- which do not possess the 3-1 chain property and are not semiorders. --@@ -245,7 +236,6 @@ -- '~~' is a symmetric relation. -- -- This is a required property.--- symmetric_eq :: Preorder r => r -> r -> Bool symmetric_eq = symmetric (~~) @@ -254,16 +244,14 @@ -- '~~' is a reflexive relation. -- -- This is a required property----reflexive_eq :: Preorder r => r ->  Bool-reflexive_eq = reflexive (~~) +reflexive_eq :: Preorder r => r -> Bool+reflexive_eq = reflexive (~~)  -- | \( \forall a, b, c: ((a = b) \wedge (b = c)) \Rightarrow (a = c) \) -- -- '~~' is a transitive relation. -- -- This is a required property.--- transitive_eq :: Preorder r => r -> r -> r -> Bool transitive_eq = transitive (~~) @@ -274,59 +262,51 @@ -- | \( \forall a: (a \# a) \) -- -- For example, ≥ is a reflexive relation but > is not.--- reflexive :: Rel r b -> r -> b-reflexive (#) a = a # a +reflexive (#) a = a # a  -- | \( \forall a: \neg (a \# a) \) -- -- For example, > is an irreflexive relation, but ≥ is not.--- irreflexive :: Rel r Bool -> r -> Bool irreflexive (#) a = not $ a # a  -- | \( \forall a, b: ((a \# b) \wedge (b \# a)) \Rightarrow (a \equiv b) \) ----- For example, the relation over the integers in which each odd number is --- related to itself is a coreflexive relation. The equality relation is the --- only example of a relation that is both reflexive and coreflexive, and any +-- For example, the relation over the integers in which each odd number is+-- related to itself is a coreflexive relation. The equality relation is the+-- only example of a relation that is both reflexive and coreflexive, and any -- coreflexive relation is a subset of the equality relation.--- coreflexive :: Rel r Bool -> Rel r Bool -> r -> r -> Bool coreflexive (%) (#) a b = (a # b) && (b # a) ==> (a % b)  -- | \( \forall a, b: (a \# b) \Rightarrow ((a \# a) \wedge (b \# b)) \)--- quasireflexive :: Rel r Bool -> r -> r -> Bool quasireflexive (#) a b = (a # b) ==> (a # a) && (b # b)  -- | \( \forall a, b, c: ((a \# b) \wedge (a \# c)) \Rightarrow (b \# c) \) -- -- For example, /=/ is a right Euclidean relation because if /x = y/ and /x = z/ then /y = z/.--- euclideanR :: Rel r Bool -> r -> r -> r -> Bool euclideanR (#) a b c = (a # b) && (a # c) ==> b # c  -- |  \( \forall a, b, c: ((b \# a) \wedge (c \# a)) \Rightarrow (b \# c) \) -- -- For example, /=/ is a left Euclidean relation because if /x = y/ and /x = z/ then /y = z/.--- euclideanL :: Rel r Bool -> r -> Rel r Bool euclideanL (#) a b c = (b # a) && (c # a) ==> b # c  -- | \( \forall a, b, c: ((a \# b) \wedge (b \# c)) \Rightarrow (a \# c) \) -- -- For example, "is ancestor of" is a transitive relation, while "is parent of" is not.--- transitive :: Rel r Bool -> r -> r -> r -> Bool transitive (#) a b c = (a # b) && (b # c) ==> a # c  -- | \( \forall a, b: ((a \# b) \vee (b \# a)) \) -- -- For example, ≥ is a connex relation, while 'divides evenly' is not.--- --- A connex relation cannot be symmetric, except for the universal relation. --+-- A connex relation cannot be symmetric, except for the universal relation. connex :: Rel r Bool -> r -> r -> Bool connex (#) a b = (a # b) || (b # a) @@ -335,26 +315,23 @@ -- A binary relation is semiconnex if it relates all pairs of _distinct_ elements in some way. -- -- A relation is connex if and only if it is semiconnex and reflexive.--- semiconnex :: Rel r Bool -> Rel r Bool -> r -> r -> Bool semiconnex (%) (#) a b = not (a % b) ==> connex (#) a b  -- | \( \forall a, b, c: ((a \# b) \vee (a \doteq b) \vee (b \# a)) \wedge \neg ((a \# b) \wedge (a \doteq b) \wedge (b \# a)) \) -- -- In other words, exactly one of \(a \# b\), \(a \doteq b\), or \(b \# a\) holds.--- 	+-- -- For example, > is a trichotomous relation, while ≥ is not. -- -- Note that @ trichotomous (>) @ should hold for any 'Ord' instance.--- trichotomous :: Rel r Bool -> Rel r Bool -> r -> r -> Bool trichotomous (%) (#) a b = xor3 (a # b) (a % b) (b # a)  -- | \( \forall a, b: (a \# b) \Leftrightarrow (b \# a) \) ----- For example, "is a blood relative of" is a symmetric relation, because +-- For example, "is a blood relative of" is a symmetric relation, because -- A is a blood relative of B if and only if B is a blood relative of A.--- symmetric :: Rel r Bool -> r -> r -> Bool symmetric (#) a b = (a # b) <=> (b # a) @@ -363,14 +340,12 @@ -- For example, > is an asymmetric relation, but ≥ is not. -- -- A relation is asymmetric if and only if it is both antisymmetric and irreflexive.---  asymmetric :: Rel r Bool -> r -> r -> Bool asymmetric (#) a b = (a # b) ==> not (b # a)  -- | \( \forall a, b: (a \# b) \wedge (b \# a) \Rightarrow a \equiv b \) ----- For example, ≥ is an antisymmetric relation; so is >, but vacuously +-- For example, ≥ is an antisymmetric relation; so is >, but vacuously -- (the condition in the definition is always false).--- antisymmetric :: Rel r Bool -> Rel r Bool -> r -> r -> Bool antisymmetric (%) (#) a b = (a # b) && (b # a) ==> (a % b)
src/Data/Order/Syntax.hs view
@@ -1,37 +1,83 @@-{-# LANGUAGE Safe #-} {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE Safe #-}+ -- | Utilities for custom preludes and RebindableSyntax. module Data.Order.Syntax (-  -- * Partial orders-    Order-  , (==),(/=)-  , (<=),(>=)-  -- * Total orders-  , Total-  , min ,max-  , compare-  , comparing-  -- * Re-exports-  , Eq.Eq()-  , Ord.Ord()+    -- * Preorders+    (<),+    (>),++    -- * Partial orders+    Order,+    (==),+    (/=),+    (<=),+    (>=),++    -- * Total orders+    Total,+    min,+    max,+    compare,+    comparing,++    -- * Re-exports+    Eq.Eq (),+    Ord.Ord (), ) where  import safe Control.Exception-import safe Data.Order import safe qualified Data.Eq as Eq import safe qualified Data.Ord as Ord+import safe Data.Order -import Prelude hiding (Eq(..),Ord(..))+import Prelude hiding (Eq (..), Ord (..)) +infix 4 <, >++-- | A strict preorder relation on /a/.+--+-- Is /x/ less than /y/?+--+-- '<' is irreflexive, asymmetric, and transitive.+--+-- > x < y = x <~ y && not (y <~ x)+-- > x < y = maybe False (< EQ) (pcompare x y)+--+-- When '<~' is antisymmetric then /a/ is a partial+-- order and we have:+--+-- > x < y = x <~ y && x /~ y+--+-- for all /x/, /y/ in /a/.+(<) :: Preorder a => a -> a -> Bool+(<) = plt++-- | A converse strict preorder relation on /a/.+--+-- Is /x/ greater than /y/?+--+-- '>' is irreflexive, asymmetric, and transitive.+--+-- > x > y = x >~ y && not (y >~ x)+-- > x > y = maybe False (> EQ) (pcompare x y)+--+-- When '<~' is antisymmetric then /a/ is a partial+-- order and we have:+--+-- > x > y = x >~ y && x /~ y+--+-- for all /x/, /y/ in /a/.+(>) :: Preorder a => a -> a -> Bool+(>) = flip (<)+ ------------------------------------------------------------------------------- -- Partial orders ------------------------------------------------------------------------------- - infix 4 ==, /=, <=, >=  -- | A wrapper around /==/ that forces /NaN == NaN/.--- (==) :: Eq.Eq a => a -> a -> Bool (==) x y = if x Eq./= x && y Eq./= y then True else x Eq.== y @@ -48,7 +94,6 @@ -- Total orders ------------------------------------------------------------------------------- - infix 4 `min`, `max`, `compare`, `comparing`  -- | Find the minimum of two values.@@ -57,11 +102,10 @@ -- -- /Note/: this function will throw a /ArithException/ on floats and rationals -- if one of the arguments is finite and the other is /NaN/.--- min :: Total a => a -> a -> a min x y = case compare x y of-  GT -> y-  _  -> x+    GT -> y+    _ -> x  -- | Find the minimum of two values. --@@ -69,11 +113,10 @@ -- -- /Note/: this function will throw a /ArithException/ on floats and rationals -- if one of the arguments is finite and the other is /NaN/.--- max :: Total a => a -> a -> a max x y = case compare x y of-  LT -> y-  _  -> x+    LT -> y+    _ -> x  -- | Compare two values in a total order. --@@ -95,15 +138,13 @@ -- -- >>> compare (0/0 :: Double) 0 -- *** Exception: divide by zero--- compare :: Total a => a -> a -> Ordering compare x y = case pcompare x y of-  Just o -> o-  Nothing -> throw DivideByZero+    Just o -> o+    Nothing -> throw DivideByZero  -- | Compare on the range of a function. -- -- > comparing p x y = compare (p x) (p y)--- comparing :: Total a => (b -> a) -> b -> b -> Ordering comparing p x y = compare (p x) (p y)
test/Test/Data/Connection.hs view
@@ -9,6 +9,7 @@ import Data.Connection.Ratio import Data.Foldable import Data.Lattice+import Data.Int import Data.Word import Data.Order import Data.Order.Extended@@ -16,7 +17,7 @@ import GHC.Real hiding (Fractional(..), (^^), (^), div) import Hedgehog import Numeric.Natural-import Prelude hiding (Eq(..),Ord(..),Bounded)+import Prelude hiding (Eq(..),Ord(..)) import qualified Hedgehog.Gen as G import qualified Hedgehog.Range as R import Data.Connection.Property as Prop@@ -24,8 +25,8 @@ import Data.Order.Property import Data.Order.Syntax -ri :: (Integral a, Lattice a) => Range a-ri = R.linearFrom 0 false true+ri :: (Integral a, Bounded a) => Range a+ri = R.linearFrom 0 minBound maxBound  ri' :: Range Integer ri' = R.linearFrom 0 (- 2^127) (2^127)@@ -62,12 +63,6 @@ -- potentially ineffiecient gen_ivl :: Preorder a => Gen a -> Gen a -> Gen (Interval a) gen_ivl g1 g2 = liftA2 (...) g1 g2 ----gen_inf :: Bounded a => Gen a -> Gen (Inf a)---gen_inf g = liftA2 (foldl' $ flip filterL) (fmap inf g) $ G.list (R.constant 0 20) g----gen_sup :: Bounded a => Gen a -> Gen (Sup a)---gen_sup g = liftA2 (foldl' $ flip filterR) (fmap sup g) $ G.list (R.constant 0 20) g  gen_maybe :: Gen a -> Gen (Maybe a) gen_maybe gen = G.frequency [(9, Just <$> gen), (1, pure Nothing)]
test/Test/Data/Connection/Float.hs view
@@ -3,7 +3,6 @@  import Data.Connection.Conn import Data.Connection.Float-import Data.Connection.Double import Data.Int import Hedgehog import Prelude hiding (Ord(..),Bounded, until)@@ -77,156 +76,18 @@   assert $ Prop.monotonic (f64i32) x x' y y'   assert $ Prop.idempotent (f64i32) x y -{---prop_connections_f32 :: Property-prop_connections_f32 = withTests 1000 . property $ do-  x <- forAll f32-  y <- forAll (gen_maybe $ G.integral ri)-  x' <- forAll f32-  y' <- forAll (gen_maybe $ G.integral ri)- -  assert $ Prop.adjoint f32i32 x y-  assert $ Prop.adjoint i32f32 y x-  assert $ Prop.closed f32i32 x-  assert $ Prop.closed i32f32 y-  assert $ Prop.kernel i32f32 x-  assert $ Prop.kernel f32i32 y-  assert $ Prop.monotonicL f32i32 x x'-  assert $ Prop.monotonicL i32f32 y y'-  assert $ Prop.monotonicR f32i32 y y'-  assert $ Prop.monotonicR i32f32 x x'-  assert $ Prop.idempotentL f32i32 x-  assert $ Prop.idempotentL i32f32 y-  assert $ Prop.idempotentR i32f32 x-  assert $ Prop.idempotentR f32i32 y--prop_connections_f64 :: Property-prop_connections_f64 = withTests 1000 . property $ do+prop_connection_f64f32 :: Property+prop_connection_f64f32 = withTests 1000 . property $ do   x <- forAll f64-  y <- forAll (gen_maybe $ G.integral ri)   x' <- forAll f64-  y' <- forAll (gen_maybe $ G.integral ri)- -  assert $ Prop.adjoint f64i64 x y-  assert $ Prop.adjoint i64f64 y x-  assert $ Prop.closed f64i64 x-  assert $ Prop.closed i64f64 y-  assert $ Prop.kernel i64f64 x-  assert $ Prop.kernel f64i64 y-  assert $ Prop.monotonicL f64i64 x x'-  assert $ Prop.monotonicL i64f64 y y'-  assert $ Prop.monotonicR f64i64 y y'-  assert $ Prop.monotonicR i64f64 x x'-  assert $ Prop.idempotentL f64i64 x-  assert $ Prop.idempotentL i64f64 y-  assert $ Prop.idempotentR i64f64 x-  assert $ Prop.idempotentR f64i64 y--prop_prd_u32 :: Property-prop_prd_u32 = withTests 1000 . property $ do-  x <- connl f32u32 <$> forAll f32-  y <- connl f32u32 <$> forAll f32-  z <- connl f32u32 <$> forAll f32-  assert $ Prop.reflexive_eq x-  assert $ Prop.reflexive_le x-  assert $ Prop.irreflexive_lt x-  assert $ Prop.symmetric x y-  assert $ Prop.asymmetric x y-  assert $ Prop.antisymmetric x y-  assert $ Prop.transitive_lt x y z-  assert $ Prop.transitive_le x y z-  assert $ Prop.transitive_eq x y z--gen_sgn :: Gen Signed-gen_sgn = Signed <$> f32--gen_ugn :: Gen Unsigned-gen_ugn = (Unsigned . abs) <$> f32--prop_connections_f32u32 :: Property-prop_connections_f32u32 = withTests 1000 . property $ do-  x <- forAll f32-  y <- Ulp32 <$> forAll (G.integral ri)-  x' <- forAll f32-  y' <- Ulp32 <$> forAll (G.integral ri)--  assert $ Prop.adjoint f32u32 x y-  assert $ Prop.adjoint u32f32 y x-  assert $ Prop.monotonicL f32u32 x x'-  assert $ Prop.monotonicL u32f32 y y'-  assert $ Prop.monotonicR f32u32 y y'-  assert $ Prop.monotonicR u32f32 x x'-  assert $ Prop.closed f32u32 x-  assert $ Prop.closed u32f32 y-  assert $ Prop.kernel u32f32 x-  assert $ Prop.kernel f32u32 y--prop_connections_f32sgn :: Property-prop_connections_f32sgn = withTests 10000 . property $ do-  x <- forAll f32-  x' <- forAll f32-  y <- forAll $ gen_sgn-  y' <- forAll $ gen_sgn--  assert $ Prop.adjoint f32sgn x y-  assert $ Prop.monotonicL f32sgn x x'-  assert $ Prop.monotonicR f32sgn y y'-  assert $ Prop.closed f32sgn x-  assert $ Prop.kernel f32sgn y--prop_connections_f32w08 :: Property-prop_connections_f32w08 = withTests 10000 . property $ do-  x <- forAll f32-  x' <- forAll f32-  y <- forAll $ gen_n5 $ G.integral (ri @Word8)-  y' <- forAll $ gen_n5 $ G.integral (ri @Word8)--  assert $ Prop.adjoint (tripl f32w08) x y-  assert $ Prop.adjoint (tripr f32w08) y x-  assert $ Prop.monotonicL (tripl f32w08) x x'-  assert $ Prop.monotonicL (tripr f32w08) y y'-  assert $ Prop.monotonicR (tripl f32w08) y y'-  assert $ Prop.monotonicR (tripr f32w08) x x'-  assert $ Prop.closed (tripl f32w08) x-  assert $ Prop.closed (tripr f32w08) y-  assert $ Prop.kernel (tripl f32w08) y-  assert $ Prop.kernel (tripr f32w08) x--prop_connections_f32w64 :: Property-prop_connections_f32w64 = withTests 1000 . property $ do-  x <- forAll f32   y <- forAll f32-  x' <- forAll f32   y' <- forAll f32-  z <- forAll (gen_n5 $ G.integral @_ @Word64 ri)-  w <- forAll (gen_n5 $ G.integral @_ @Word64 ri)-  z' <- forAll (gen_n5 $ G.integral @_ @Word64 ri)-  w' <- forAll (gen_n5 $ G.integral @_ @Word64 ri)-  exy <- forAll $ G.element [Left x, Right y]-  exy' <- forAll $ G.element [Left x', Right y']-  ezw <- forAll $ G.element [Left z, Right w]-  ezw' <- forAll $ G.element [Left z', Right w'] -  assert $ Prop.closed (idx @Float) x --TODO in Index.hs-  assert $ Prop.kernel (idx @Float) z-  assert $ Prop.monotonicL (idx @Float) x x'-  assert $ Prop.monotonicR (idx @Float) z z'-  assert $ Prop.adjoint (idx @Float) x z--  assert $ Prop.closed (idx @(Float,Float)) (x,y)-  assert $ Prop.kernel (idx @(Float,Float)) (z,w)-  assert $ Prop.monotonicL (idx @(Float,Float)) (x,y) (x',y')-  assert $ Prop.monotonicR (idx @(Float,Float)) (z,w) (z',w')-  assert $ Prop.adjoint (idx @(Float,Float)) (x,y)(z,w)--  assert $ Prop.closed (idx @(EitheR Float Float)) exy-  assert $ Prop.kernel (idx @(EitheR Float Float)) ezw-  assert $ Prop.monotonicL (idx @(EitheR Float Float)) exy exy'-  assert $ Prop.monotonicR (idx @(EitheR Float Float)) ezw ezw'-  assert $ Prop.adjoint (idx @(EitheR Float Float)) exy ezw--}-+  assert $ Prop.adjoint (f64f32) x y+  assert $ Prop.closed (f64f32) x+  assert $ Prop.kernel (f64f32) y+  assert $ Prop.monotonic (f64f32) x x' y y'+  assert $ Prop.idempotent (f64f32) x y  tests :: IO Bool tests = checkParallel $$(discover)
test/Test/Data/Connection/Int.hs view
@@ -2,31 +2,85 @@ module Test.Data.Connection.Int where  import Data.Connection.Int-import Data.Connection.Conn import Data.Int import Data.Word import Hedgehog-import Prelude hiding (Bounded) import Test.Data.Connection import qualified Data.Connection.Property as Prop import qualified Hedgehog.Gen as G -prop_connectionsL :: Property-prop_connectionsL = withTests 1000 . property $ do+prop_connections_int16 :: Property+prop_connections_int16 = withTests 1000 . property $ do    i08 <- forAll $ G.integral (ri @Int8)   w08 <- forAll $ G.integral (ri @Word8)+  i16 <- forAll $ gen_maybe $ G.integral (ri @Int16)++  i08' <- forAll $ G.integral (ri @Int8)+  w08' <- forAll $ G.integral (ri @Word8)+  i16' <- forAll $ gen_maybe $ G.integral (ri @Int16)++  assert $ Prop.adjointL w08i16 w08 i16+  assert $ Prop.closedL w08i16 w08+  assert $ Prop.kernelL w08i16 i16+  assert $ Prop.monotonicL w08i16 w08 w08' i16 i16'+  assert $ Prop.idempotentL w08i16 w08 i16++  assert $ Prop.adjointL i08i16 i08 i16+  assert $ Prop.closedL i08i16 i08+  assert $ Prop.kernelL i08i16 i16+  assert $ Prop.monotonicL i08i16 i08 i08' i16 i16'+  assert $ Prop.idempotentL i08i16 i08 i16++prop_connections_int32 :: Property+prop_connections_int32 = withTests 1000 . property $ do++  i08 <- forAll $ G.integral (ri @Int8)+  w08 <- forAll $ G.integral (ri @Word8)   i16 <- forAll $ G.integral (ri @Int16)   w16 <- forAll $ G.integral (ri @Word16)+  i32 <- forAll $ gen_maybe $ G.integral (ri @Int32)++  i08' <- forAll $ G.integral (ri @Int8)+  w08' <- forAll $ G.integral (ri @Word8)+  i16' <- forAll $ G.integral (ri @Int16)+  w16' <- forAll $ G.integral (ri @Word16)+  i32' <- forAll $ gen_maybe $ G.integral (ri @Int32)++  assert $ Prop.adjointL w08i32 w08 i32+  assert $ Prop.closedL w08i32 w08+  assert $ Prop.kernelL w08i32 i32+  assert $ Prop.monotonicL w08i32 w08 w08' i32 i32'+  assert $ Prop.idempotentL w08i32 w08 i32+  +  assert $ Prop.adjointL w16i32 w16 i32+  assert $ Prop.closedL w16i32 w16+  assert $ Prop.kernelL w16i32 i32+  assert $ Prop.monotonicL w16i32 w16 w16' i32 i32'+  assert $ Prop.idempotentL w16i32 w16 i32++  assert $ Prop.adjointL i08i32 i08 i32+  assert $ Prop.closedL i08i32 i08+  assert $ Prop.kernelL i08i32 i32+  assert $ Prop.monotonicL i08i32 i08 i08' i32 i32'+  assert $ Prop.idempotentL i08i32 i08 i32+  +  assert $ Prop.adjointL i16i32 i16 i32+  assert $ Prop.closedL i16i32 i16+  assert $ Prop.kernelL i16i32 i32+  assert $ Prop.monotonicL i16i32 i16 i16' i32 i32'+  assert $ Prop.idempotentL i16i32 i16 i32++prop_connections_int64 :: Property+prop_connections_int64 = withTests 1000 . property $ do++  i08 <- forAll $ G.integral (ri @Int8)+  w08 <- forAll $ G.integral (ri @Word8)+  i16 <- forAll $ G.integral (ri @Int16)+  w16 <- forAll $ G.integral (ri @Word16)   i32 <- forAll $ G.integral (ri @Int32)   w32 <- forAll $ G.integral (ri @Word32)-  i64 <- forAll $ G.integral (ri @Int64)-  w64 <- forAll $ G.integral (ri @Word64)-  ixx <- forAll $ G.integral (ri @Int)-  wxx <- forAll $ G.integral (ri @Word)-  int <- forAll $ G.integral ri'-  nat <- forAll $ G.integral rn-  mnt <- forAll $ gen_maybe (G.integral ri')+  i64 <- forAll $ gen_maybe $ G.integral (ri @Int64)    i08' <- forAll $ G.integral (ri @Int8)   w08' <- forAll $ G.integral (ri @Word8)@@ -34,57 +88,112 @@   w16' <- forAll $ G.integral (ri @Word16)   i32' <- forAll $ G.integral (ri @Int32)   w32' <- forAll $ G.integral (ri @Word32)-  i64' <- forAll $ G.integral (ri @Int64)-  w64' <- forAll $ G.integral (ri @Word64)-  ixx' <- forAll $ G.integral (ri @Int)-  wxx' <- forAll $ G.integral (ri @Word)-  int' <- forAll $ G.integral ri'-  nat' <- forAll $ G.integral rn-  mnt' <- forAll $ gen_maybe (G.integral ri')+  i64' <- forAll $ gen_maybe $ G.integral (ri @Int64) -  assert $ Prop.adjointL intnat  int nat-  --assert $ Prop.adjointL natint  nat mnt-  assert $ Prop.adjointL ixxwxx  ixx wxx-  assert $ Prop.adjointL i64w64  i64 w64-  assert $ Prop.adjointL i32w32  i32 w32-  assert $ Prop.adjointL i16w16  i16 w16-  assert $ Prop.adjointL i08w08  i08 w08+  assert $ Prop.adjointL w08i64 w08 i64+  assert $ Prop.closedL w08i64 w08+  assert $ Prop.kernelL w08i64 i64+  assert $ Prop.monotonicL w08i64 w08 w08' i64 i64'+  assert $ Prop.idempotentL w08i64 w08 i64+  +  assert $ Prop.adjointL w16i64 w16 i64+  assert $ Prop.closedL w16i64 w16+  assert $ Prop.kernelL w16i64 i64+  assert $ Prop.monotonicL w16i64 w16 w16' i64 i64'+  assert $ Prop.idempotentL w16i64 w16 i64+  +  assert $ Prop.adjointL w32i64 w32 i64+  assert $ Prop.closedL w32i64 w32+  assert $ Prop.kernelL w32i64 i64+  assert $ Prop.monotonicL w32i64 w32 w32' i64 i64'+  assert $ Prop.idempotentL w32i64 w32 i64 -  assert $ Prop.closedL intnat  int-  --assert $ Prop.closedL natint  nat-  assert $ Prop.closedL ixxwxx  ixx-  assert $ Prop.closedL i64w64  i64-  assert $ Prop.closedL i32w32  i32-  assert $ Prop.closedL i16w16  i16-  assert $ Prop.closedL i08w08  i08+  assert $ Prop.adjointL i08i64 i08 i64+  assert $ Prop.closedL i08i64 i08+  assert $ Prop.kernelL i08i64 i64+  assert $ Prop.monotonicL i08i64 i08 i08' i64 i64'+  assert $ Prop.idempotentL i08i64 i08 i64+  +  assert $ Prop.adjointL i16i64 i16 i64+  assert $ Prop.closedL i16i64 i16+  assert $ Prop.kernelL i16i64 i64+  assert $ Prop.monotonicL i16i64 i16 i16' i64 i64'+  assert $ Prop.idempotentL i16i64 i16 i64+  +  assert $ Prop.adjointL i32i64 i32 i64+  assert $ Prop.closedL i32i64 i32+  assert $ Prop.kernelL i32i64 i64+  assert $ Prop.monotonicL i32i64 i32 i32' i64 i64'+  assert $ Prop.idempotentL i32i64 i32 i64 -  assert $ Prop.kernelL intnat  nat-  --assert $ Prop.kernelL natint  mnt-  assert $ Prop.kernelL ixxwxx  wxx-  assert $ Prop.kernelL i64w64  w64-  assert $ Prop.kernelL i32w32  w32-  assert $ Prop.kernelL i16w16  w16-  assert $ Prop.kernelL i08w08  w08+prop_connections_int :: Property+prop_connections_int = withTests 1000 . property $ do -  assert $ Prop.monotonicL intnat  int int' nat nat'-  --assert $ Prop.monotonicL natint  nat nat' mnt mnt'-  assert $ Prop.monotonicL ixxwxx  ixx ixx' wxx wxx'-  assert $ Prop.monotonicL i64w64  i64 i64' w64 w64'-  assert $ Prop.monotonicL i32w32  i32 i32' w32 w32'-  assert $ Prop.monotonicL i16w16  i16 i16' w16 w16'-  assert $ Prop.monotonicL i08w08  i08 i08' w08 w08'+  i08 <- forAll $ G.integral (ri @Int8)+  w08 <- forAll $ G.integral (ri @Word8)+  i16 <- forAll $ G.integral (ri @Int16)+  w16 <- forAll $ G.integral (ri @Word16)+  i32 <- forAll $ G.integral (ri @Int32)+  w32 <- forAll $ G.integral (ri @Word32)+  i64 <- forAll $ G.integral (ri @Int64)+  ixx <- forAll $ gen_maybe $ G.integral (ri @Int)+  int <- forAll $ G.integral (ri @Int) -  assert $ Prop.idempotentL intnat  int nat-  -- assert $ Prop.idempotentL natint  nat mnt-  assert $ Prop.idempotentL ixxwxx  ixx wxx-  assert $ Prop.idempotentL i64w64  i64 w64-  assert $ Prop.idempotentL i32w32  i32 w32-  assert $ Prop.idempotentL i16w16  i16 w16-  assert $ Prop.idempotentL i08w08  i08 w08+  i08' <- forAll $ G.integral (ri @Int8)+  w08' <- forAll $ G.integral (ri @Word8)+  i16' <- forAll $ G.integral (ri @Int16)+  w16' <- forAll $ G.integral (ri @Word16)+  i32' <- forAll $ G.integral (ri @Int32)+  w32' <- forAll $ G.integral (ri @Word32)+  i64' <- forAll $ G.integral (ri @Int64)+  ixx' <- forAll $ gen_maybe $ G.integral (ri @Int)+  int' <- forAll $ G.integral (ri @Int) -prop_connectionsR :: Property-prop_connectionsR = withTests 1000 . property $ do+  assert $ Prop.adjointL w08ixx w08 ixx+  assert $ Prop.closedL w08ixx w08+  assert $ Prop.kernelL w08ixx ixx+  assert $ Prop.monotonicL w08ixx w08 w08' ixx ixx'+  assert $ Prop.idempotentL w08ixx w08 ixx+  +  assert $ Prop.adjointL w16ixx w16 ixx+  assert $ Prop.closedL w16ixx w16+  assert $ Prop.kernelL w16ixx ixx+  assert $ Prop.monotonicL w16ixx w16 w16' ixx ixx'+  assert $ Prop.idempotentL w16ixx w16 ixx+  +  assert $ Prop.adjointL w32ixx w32 ixx+  assert $ Prop.closedL w32ixx w32+  assert $ Prop.kernelL w32ixx ixx+  assert $ Prop.monotonicL w32ixx w32 w32' ixx ixx'+  assert $ Prop.idempotentL w32ixx w32 ixx +  assert $ Prop.adjointL i08ixx i08 ixx+  assert $ Prop.closedL i08ixx i08+  assert $ Prop.kernelL i08ixx ixx+  assert $ Prop.monotonicL i08ixx i08 i08' ixx ixx'+  assert $ Prop.idempotentL i08ixx i08 ixx+  +  assert $ Prop.adjointL i16ixx i16 ixx+  assert $ Prop.closedL i16ixx i16+  assert $ Prop.kernelL i16ixx ixx+  assert $ Prop.monotonicL i16ixx i16 i16' ixx ixx'+  assert $ Prop.idempotentL i16ixx i16 ixx+  +  assert $ Prop.adjointL i32ixx i32 ixx+  assert $ Prop.closedL i32ixx i32+  assert $ Prop.kernelL i32ixx ixx+  assert $ Prop.monotonicL i32ixx i32 i32' ixx ixx'+  assert $ Prop.idempotentL i32ixx i32 ixx+  +  assert $ Prop.adjoint i64ixx i64 int+  assert $ Prop.closed i64ixx i64+  assert $ Prop.kernel i64ixx int+  assert $ Prop.monotonic i64ixx i64 i64' int int'+  assert $ Prop.idempotent i64ixx i64 int++prop_connections_integer :: Property+prop_connections_integer = withTests 1000 . property $ do+   i08 <- forAll $ G.integral (ri @Int8)   w08 <- forAll $ G.integral (ri @Word8)   i16 <- forAll $ G.integral (ri @Int16)@@ -95,9 +204,8 @@   w64 <- forAll $ G.integral (ri @Word64)   ixx <- forAll $ G.integral (ri @Int)   wxx <- forAll $ G.integral (ri @Word)-  int <- forAll $ G.integral ri'+  int <- forAll $ gen_maybe $ G.integral ri'   nat <- forAll $ G.integral rn-  mnt <- forAll $ gen_maybe (G.integral ri')    i08' <- forAll $ G.integral (ri @Int8)   w08' <- forAll $ G.integral (ri @Word8)@@ -109,49 +217,77 @@   w64' <- forAll $ G.integral (ri @Word64)   ixx' <- forAll $ G.integral (ri @Int)   wxx' <- forAll $ G.integral (ri @Word)-  int' <- forAll $ G.integral ri'+  int' <- forAll $ gen_maybe (G.integral ri')   nat' <- forAll $ G.integral rn-  mnt' <- forAll $ gen_maybe (G.integral ri')+  +  assert $ Prop.adjointL w08int w08 int+  assert $ Prop.closedL w08int w08+  assert $ Prop.kernelL w08int int+  assert $ Prop.monotonicL w08int w08 w08' int int'+  assert $ Prop.idempotentL w08int w08 int+  +  assert $ Prop.adjointL w16int w16 int+  assert $ Prop.closedL w16int w16+  assert $ Prop.kernelL w16int int+  assert $ Prop.monotonicL w16int w16 w16' int int'+  assert $ Prop.idempotentL w16int w16 int+  +  assert $ Prop.adjointL w32int w32 int+  assert $ Prop.closedL w32int w32+  assert $ Prop.kernelL w32int int+  assert $ Prop.monotonicL w32int w32 w32' int int'+  assert $ Prop.idempotentL w32int w32 int+  +  assert $ Prop.adjointL w64int w64 int+  assert $ Prop.closedL w64int w64+  assert $ Prop.kernelL w64int int+  assert $ Prop.monotonicL w64int w64 w64' int int'+  assert $ Prop.idempotentL w64int w64 int+ +  assert $ Prop.adjointL wxxint wxx int+  assert $ Prop.closedL wxxint wxx+  assert $ Prop.kernelL wxxint int+  assert $ Prop.monotonicL wxxint wxx wxx' int int'+  assert $ Prop.idempotentL wxxint wxx int -  assert $ Prop.adjointR (swapR intnat) nat int-  -- assert $ Prop.adjointR (swapR natint) mnt nat-  assert $ Prop.adjointR (swapR ixxwxx) wxx ixx-  assert $ Prop.adjointR (swapR i64w64) w64 i64-  assert $ Prop.adjointR (swapR i32w32) w32 i32-  assert $ Prop.adjointR (swapR i16w16) w16 i16-  assert $ Prop.adjointR (swapR i08w08) w08 i08+  assert $ Prop.adjointL natint nat int+  assert $ Prop.closedL natint nat+  assert $ Prop.kernelL natint int+  assert $ Prop.monotonicL natint nat nat' int int'+  assert $ Prop.idempotentL natint nat int+ +  +  assert $ Prop.adjointL i08int i08 int+  assert $ Prop.closedL i08int i08+  assert $ Prop.kernelL i08int int+  assert $ Prop.monotonicL i08int i08 i08' int int'+  assert $ Prop.idempotentL i08int i08 int+  +  assert $ Prop.adjointL i16int i16 int+  assert $ Prop.closedL i16int i16+  assert $ Prop.kernelL i16int int+  assert $ Prop.monotonicL i16int i16 i16' int int'+  assert $ Prop.idempotentL i16int i16 int+  +  assert $ Prop.adjointL i32int i32 int+  assert $ Prop.closedL i32int i32+  assert $ Prop.kernelL i32int int+  assert $ Prop.monotonicL i32int i32 i32' int int'+  assert $ Prop.idempotentL i32int i32 int+  +  assert $ Prop.adjointL i64int i64 int+  assert $ Prop.closedL i64int i64+  assert $ Prop.kernelL i64int int+  assert $ Prop.monotonicL i64int i64 i64' int int'+  assert $ Prop.idempotentL i64int i64 int+ +  assert $ Prop.adjointL ixxint ixx int+  assert $ Prop.closedL ixxint ixx+  assert $ Prop.kernelL ixxint int+  assert $ Prop.monotonicL ixxint ixx ixx' int int'+  assert $ Prop.idempotentL ixxint ixx int -  assert $ Prop.closedR (swapR intnat) nat-  --assert $ Prop.closedR (swapR natint) mnt-  assert $ Prop.closedR (swapR ixxwxx) wxx-  assert $ Prop.closedR (swapR i64w64) w64-  assert $ Prop.closedR (swapR i32w32) w32-  assert $ Prop.closedR (swapR i16w16) w16-  assert $ Prop.closedR (swapR i08w08) w08 -  assert $ Prop.kernelR (swapR intnat) int-  --assert $ Prop.kernelR (swapR natint) nat-  assert $ Prop.kernelR (swapR ixxwxx) ixx-  assert $ Prop.kernelR (swapR i64w64) i64-  assert $ Prop.kernelR (swapR i32w32) i32-  assert $ Prop.kernelR (swapR i16w16) i16-  assert $ Prop.kernelR (swapR i08w08) i08--  assert $ Prop.monotonicR (swapR intnat)  nat nat' int int'-  -- assert $ Prop.monotonicR (swapR natint)  mnt mnt' nat nat'-  assert $ Prop.monotonicR (swapR ixxwxx)  wxx wxx' ixx ixx'-  assert $ Prop.monotonicR (swapR i64w64)  w64 w64' i64 i64'-  assert $ Prop.monotonicR (swapR i32w32)  w32 w32' i32 i32'-  assert $ Prop.monotonicR (swapR i16w16)  w16 w16' i16 i16'-  assert $ Prop.monotonicR (swapR i08w08)  w08 w08' i08 i08'--  assert $ Prop.idempotentR (swapR intnat) nat int-  -- assert $ Prop.idempotentR (swapR natint) mnt nat-  assert $ Prop.idempotentR (swapR ixxwxx) wxx ixx-  assert $ Prop.idempotentR (swapR i64w64) w64 i64-  assert $ Prop.idempotentR (swapR i32w32) w32 i32-  assert $ Prop.idempotentR (swapR i16w16) w16 i16-  assert $ Prop.idempotentR (swapR i08w08) w08 i08  tests :: IO Bool tests = checkParallel $$(discover)
test/Test/Data/Connection/Word.hs view
@@ -3,25 +3,116 @@  import Data.Int import Data.Word-import Data.Connection.Conn import Data.Connection.Word import Hedgehog import Test.Data.Connection import qualified Data.Connection.Property as Prop import qualified Hedgehog.Gen as G -prop_connections :: Property-prop_connections = withTests 1000 . property $ do+prop_connections_word8 :: Property+prop_connections_word8 = withTests 1000 . property $ do+  i08 <- forAll $ G.integral (ri @Int8)+  w08 <- forAll $ G.integral (ri @Word8) +  i08' <- forAll $ G.integral (ri @Int8)+  w08' <- forAll $ G.integral (ri @Word8)++  assert $ Prop.adjointL i08w08 i08 w08+  assert $ Prop.closedL i08w08 i08+  assert $ Prop.kernelL i08w08 w08+  assert $ Prop.monotonicL i08w08 i08 i08' w08 w08'+  assert $ Prop.idempotentL i08w08 i08 w08++prop_connections_word16 :: Property+prop_connections_word16 = withTests 1000 . property $ do+   i08 <- forAll $ G.integral (ri @Int8)   w08 <- forAll $ G.integral (ri @Word8)   i16 <- forAll $ G.integral (ri @Int16)   w16 <- forAll $ G.integral (ri @Word16)++  i08' <- forAll $ G.integral (ri @Int8)+  w08' <- forAll $ G.integral (ri @Word8)+  i16' <- forAll $ G.integral (ri @Int16)+  w16' <- forAll $ G.integral (ri @Word16)+  +  assert $ Prop.adjointL w08w16 w08 w16+  assert $ Prop.closedL w08w16 w08+  assert $ Prop.kernelL w08w16 w16+  assert $ Prop.monotonicL w08w16 w08 w08' w16 w16'+  assert $ Prop.idempotentL w08w16 w08 w16+  +  assert $ Prop.adjointL i08w16 i08 w16+  assert $ Prop.closedL i08w16 i08+  assert $ Prop.kernelL i08w16 w16+  assert $ Prop.monotonicL i08w16 i08 i08' w16 w16'+  assert $ Prop.idempotentL i08w16 i08 w16+  +  assert $ Prop.adjointL i16w16 i16 w16+  assert $ Prop.closedL i16w16 i16+  assert $ Prop.kernelL i16w16 w16+  assert $ Prop.monotonicL i16w16 i16 i16' w16 w16'+  assert $ Prop.idempotentL i16w16 i16 w16++prop_connections_word32 :: Property+prop_connections_word32 = withTests 1000 . property $ do++  i08 <- forAll $ G.integral (ri @Int8)+  w08 <- forAll $ G.integral (ri @Word8)+  i16 <- forAll $ G.integral (ri @Int16)+  w16 <- forAll $ G.integral (ri @Word16)   i32 <- forAll $ G.integral (ri @Int32)   w32 <- forAll $ G.integral (ri @Word32)++  i08' <- forAll $ G.integral (ri @Int8)+  w08' <- forAll $ G.integral (ri @Word8)+  i16' <- forAll $ G.integral (ri @Int16)+  w16' <- forAll $ G.integral (ri @Word16)+  i32' <- forAll $ G.integral (ri @Int32)+  w32' <- forAll $ G.integral (ri @Word32)+  +  assert $ Prop.adjointL w08w32 w08 w32+  assert $ Prop.closedL w08w32 w08+  assert $ Prop.kernelL w08w32 w32+  assert $ Prop.monotonicL w08w32 w08 w08' w32 w32'+  assert $ Prop.idempotentL w08w32 w08 w32++  assert $ Prop.adjointL w16w32 w16 w32+  assert $ Prop.closedL w16w32 w16+  assert $ Prop.kernelL w16w32 w32+  assert $ Prop.monotonicL w16w32 w16 w16' w32 w32'+  assert $ Prop.idempotentL w16w32 w16 w32+  +  assert $ Prop.adjointL i08w32 i08 w32+  assert $ Prop.closedL i08w32 i08+  assert $ Prop.kernelL i08w32 w32+  assert $ Prop.monotonicL i08w32 i08 i08' w32 w32'+  assert $ Prop.idempotentL i08w32 i08 w32++  assert $ Prop.adjointL i16w32 i16 w32+  assert $ Prop.closedL i16w32 i16+  assert $ Prop.kernelL i16w32 w32+  assert $ Prop.monotonicL i16w32 i16 i16' w32 w32'+  assert $ Prop.idempotentL i16w32 i16 w32++  assert $ Prop.adjointL i32w32 i32 w32+  assert $ Prop.closedL i32w32 i32+  assert $ Prop.kernelL i32w32 w32+  assert $ Prop.idempotentL i32w32 i32 w32+  assert $ Prop.monotonicL i32w32 i32 i32' w32 w32'++prop_connections_word64 :: Property+prop_connections_word64 = withTests 1000 . property $ do++  i08 <- forAll $ G.integral (ri @Int8)+  w08 <- forAll $ G.integral (ri @Word8)+  i16 <- forAll $ G.integral (ri @Int16)+  w16 <- forAll $ G.integral (ri @Word16)+  i32 <- forAll $ G.integral (ri @Int32)+  w32 <- forAll $ G.integral (ri @Word32)   i64 <- forAll $ G.integral (ri @Int64)   w64 <- forAll $ G.integral (ri @Word64)-  nat <- forAll $ G.integral rn+  ixx <- forAll $ G.integral (ri @Int)    i08' <- forAll $ G.integral (ri @Int8)   w08' <- forAll $ G.integral (ri @Word8)@@ -31,82 +122,230 @@   w32' <- forAll $ G.integral (ri @Word32)   i64' <- forAll $ G.integral (ri @Int64)   w64' <- forAll $ G.integral (ri @Word64)-  nat' <- forAll $ G.integral rn+  ixx' <- forAll $ G.integral (ri @Int) -  assert $ Prop.adjointL w64nat w64 nat-  assert $ Prop.adjointL w64i64 w64 i64-  assert $ Prop.adjointL w32nat w32 nat-  assert $ Prop.adjointL w32w64 w32 w64-  assert $ Prop.adjointL w32i32 w32 i32-  assert $ Prop.adjointL w16nat w16 nat-  assert $ Prop.adjointL w16w64 w16 w64-  assert $ Prop.adjointL w16w32 w16 w32-  assert $ Prop.adjointL w16i16 w16 i16-  assert $ Prop.adjointL w08nat w08 nat   assert $ Prop.adjointL w08w64 w08 w64-  assert $ Prop.adjointL w08w32 w08 w32-  assert $ Prop.adjointL w08w16 w08 w16-  assert $ Prop.adjointL w08i08 w08 i08+  assert $ Prop.closedL w08w64 w08+  assert $ Prop.kernelL w08w64 w64+  assert $ Prop.monotonicL w08w64 w08 w08' w64 w64'+  assert $ Prop.idempotentL w08w64 w08 w64 -  assert $ Prop.closedL w64nat w64-  assert $ Prop.closedL w64i64 w64-  assert $ Prop.closedL w32nat w32-  assert $ Prop.closedL w32w64 w32-  assert $ Prop.closedL w32i32 w32-  assert $ Prop.closedL w16nat w16+  assert $ Prop.adjointL w16w64 w16 w64   assert $ Prop.closedL w16w64 w16-  assert $ Prop.closedL w16w32 w16-  assert $ Prop.closedL w16i16 w16-  assert $ Prop.closedL w08nat w08-  assert $ Prop.closedL w08w64 w08-  assert $ Prop.closedL w08w32 w08-  assert $ Prop.closedL w08w16 w08-  assert $ Prop.closedL w08i08 w08+  assert $ Prop.kernelL w16w64 w64+  assert $ Prop.monotonicL w16w64 w16 w16' w64 w64'+  assert $ Prop.idempotentL w16w64 w16 w64 -  assert $ Prop.kernelL w64nat nat-  assert $ Prop.kernelL w64i64 i64-  assert $ Prop.kernelL w32nat nat+  assert $ Prop.adjointL w32w64 w32 w64+  assert $ Prop.closedL w32w64 w32   assert $ Prop.kernelL w32w64 w64-  assert $ Prop.kernelL w32i32 i32-  assert $ Prop.kernelL w16nat nat-  assert $ Prop.kernelL w16w64 w64-  assert $ Prop.kernelL w16w32 w32-  assert $ Prop.kernelL w16i16 i16+  assert $ Prop.monotonicL w32w64 w32 w32' w64 w64'+  assert $ Prop.idempotentL w32w64 w32 w64+  +  assert $ Prop.adjointL i08w64 i08 w64+  assert $ Prop.closedL i08w64 i08+  assert $ Prop.kernelL i08w64 w64+  assert $ Prop.monotonicL i08w64 i08 i08' w64 w64'+  assert $ Prop.idempotentL i08w64 i08 w64++  assert $ Prop.adjointL i16w64 i16 w64+  assert $ Prop.closedL i16w64 i16+  assert $ Prop.kernelL i16w64 w64+  assert $ Prop.monotonicL i16w64 i16 i16' w64 w64'+  assert $ Prop.idempotentL i16w64 i16 w64++  assert $ Prop.adjointL i32w64 i32 w64+  assert $ Prop.closedL i32w64 i32+  assert $ Prop.kernelL i32w64 w64+  assert $ Prop.idempotentL i32w64 i32 w64+  assert $ Prop.monotonicL i32w64 i32 i32' w64 w64'++  assert $ Prop.adjointL i64w64 i64 w64+  assert $ Prop.closedL i64w64 i64+  assert $ Prop.kernelL i64w64 w64+  assert $ Prop.idempotentL i64w64 i64 w64+  assert $ Prop.monotonicL i64w64 i64 i64' w64 w64'++  assert $ Prop.adjointL ixxw64 ixx w64+  assert $ Prop.closedL ixxw64 ixx+  assert $ Prop.kernelL ixxw64 w64+  assert $ Prop.idempotentL ixxw64 ixx w64+  assert $ Prop.monotonicL ixxw64 ixx ixx' w64 w64'++prop_connections_word :: Property+prop_connections_word = withTests 1000 . property $ do++  i08 <- forAll $ G.integral (ri @Int8)+  w08 <- forAll $ G.integral (ri @Word8)+  i16 <- forAll $ G.integral (ri @Int16)+  w16 <- forAll $ G.integral (ri @Word16)+  i32 <- forAll $ G.integral (ri @Int32)+  w32 <- forAll $ G.integral (ri @Word32)+  i64 <- forAll $ G.integral (ri @Int64)+  w64 <- forAll $ G.integral (ri @Word64)+  ixx <- forAll $ G.integral (ri @Int)+  wxx <- forAll $ G.integral (ri @Word)++  i08' <- forAll $ G.integral (ri @Int8)+  w08' <- forAll $ G.integral (ri @Word8)+  i16' <- forAll $ G.integral (ri @Int16)+  w16' <- forAll $ G.integral (ri @Word16)+  i32' <- forAll $ G.integral (ri @Int32)+  w32' <- forAll $ G.integral (ri @Word32)+  i64' <- forAll $ G.integral (ri @Int64)+  w64' <- forAll $ G.integral (ri @Word64)+  ixx' <- forAll $ G.integral (ri @Int)+  wxx' <- forAll $ G.integral (ri @Word)++  assert $ Prop.adjointL w08wxx w08 wxx+  assert $ Prop.closedL w08wxx w08+  assert $ Prop.kernelL w08wxx wxx+  assert $ Prop.monotonicL w08wxx w08 w08' wxx wxx'+  assert $ Prop.idempotentL w08wxx w08 wxx++  assert $ Prop.adjointL w16wxx w16 wxx+  assert $ Prop.closedL w16wxx w16+  assert $ Prop.kernelL w16wxx wxx+  assert $ Prop.monotonicL w16wxx w16 w16' wxx wxx'+  assert $ Prop.idempotentL w16wxx w16 wxx++  assert $ Prop.adjointL w32wxx w32 wxx+  assert $ Prop.closedL w32wxx w32+  assert $ Prop.kernelL w32wxx wxx+  assert $ Prop.monotonicL w32wxx w32 w32' wxx wxx'+  assert $ Prop.idempotentL w32wxx w32 wxx++  assert $ Prop.adjoint w64wxx w64 wxx+  assert $ Prop.closed w64wxx w64+  assert $ Prop.kernel w64wxx wxx+  assert $ Prop.monotonic w64wxx w64 w64' wxx wxx'+  assert $ Prop.idempotent w64wxx w64 wxx+  +  assert $ Prop.adjointL i08wxx i08 wxx+  assert $ Prop.closedL i08wxx i08+  assert $ Prop.kernelL i08wxx wxx+  assert $ Prop.monotonicL i08wxx i08 i08' wxx wxx'+  assert $ Prop.idempotentL i08wxx i08 wxx++  assert $ Prop.adjointL i16wxx i16 wxx+  assert $ Prop.closedL i16wxx i16+  assert $ Prop.kernelL i16wxx wxx+  assert $ Prop.monotonicL i16wxx i16 i16' wxx wxx'+  assert $ Prop.idempotentL i16wxx i16 wxx++  assert $ Prop.adjointL i32wxx i32 wxx+  assert $ Prop.closedL i32wxx i32+  assert $ Prop.kernelL i32wxx wxx+  assert $ Prop.idempotentL i32wxx i32 wxx+  assert $ Prop.monotonicL i32wxx i32 i32' wxx wxx'++  assert $ Prop.adjointL i64wxx i64 wxx+  assert $ Prop.closedL i64wxx i64+  assert $ Prop.kernelL i64wxx wxx+  assert $ Prop.idempotentL i64wxx i64 wxx+  assert $ Prop.monotonicL i64wxx i64 i64' wxx wxx'++  assert $ Prop.adjointL ixxwxx ixx wxx+  assert $ Prop.closedL ixxwxx ixx+  assert $ Prop.kernelL ixxwxx wxx+  assert $ Prop.idempotentL ixxwxx ixx wxx+  assert $ Prop.monotonicL ixxwxx ixx ixx' wxx wxx'++prop_connections_natural :: Property+prop_connections_natural = withTests 1000 . property $ do++  i08 <- forAll $ G.integral (ri @Int8)+  w08 <- forAll $ G.integral (ri @Word8)+  i16 <- forAll $ G.integral (ri @Int16)+  w16 <- forAll $ G.integral (ri @Word16)+  i32 <- forAll $ G.integral (ri @Int32)+  w32 <- forAll $ G.integral (ri @Word32)+  i64 <- forAll $ G.integral (ri @Int64)+  w64 <- forAll $ G.integral (ri @Word64)+  ixx <- forAll $ G.integral (ri @Int)+  wxx <- forAll $ G.integral (ri @Word)+  int <- forAll $ G.integral ri''+  nat <- forAll $ G.integral rn++  i08' <- forAll $ G.integral (ri @Int8)+  w08' <- forAll $ G.integral (ri @Word8)+  i16' <- forAll $ G.integral (ri @Int16)+  w16' <- forAll $ G.integral (ri @Word16)+  i32' <- forAll $ G.integral (ri @Int32)+  w32' <- forAll $ G.integral (ri @Word32)+  i64' <- forAll $ G.integral (ri @Int64)+  w64' <- forAll $ G.integral (ri @Word64)+  ixx' <- forAll $ G.integral (ri @Int)+  wxx' <- forAll $ G.integral (ri @Word)+  int' <- forAll $ G.integral ri''+  nat' <- forAll $ G.integral rn++  assert $ Prop.adjointL w08nat w08 nat+  assert $ Prop.closedL w08nat w08   assert $ Prop.kernelL w08nat nat-  assert $ Prop.kernelL w08w64 w64-  assert $ Prop.kernelL w08w32 w32-  assert $ Prop.kernelL w08w16 w16-  assert $ Prop.kernelL w08i08 i08+  assert $ Prop.monotonicL w08nat w08 w08' nat nat'+  assert $ Prop.idempotentL w08nat w08 nat -  assert $ Prop.monotonicL w64nat w64 w64' nat nat'-  assert $ Prop.monotonicL w64i64 w64 w64' i64 i64'-  assert $ Prop.monotonicL w32nat w32 w32' nat nat'-  assert $ Prop.monotonicL w32w64 w32 w32' w64 w64'-  assert $ Prop.monotonicL w32i32 w32 w32' i32 i32'+  assert $ Prop.adjointL w16nat w16 nat+  assert $ Prop.closedL w16nat w16+  assert $ Prop.kernelL w16nat nat   assert $ Prop.monotonicL w16nat w16 w16' nat nat'-  assert $ Prop.monotonicL w16w64 w16 w16' w64 w64'-  assert $ Prop.monotonicL w16w32 w16 w16' w32 w32'-  assert $ Prop.monotonicL w16i16 w16 w16' i16 i16'-  assert $ Prop.monotonicL w08nat w08 w08' nat nat'-  assert $ Prop.monotonicL w08w64 w08 w08' w64 w64'-  assert $ Prop.monotonicL w08w32 w08 w08' w32 w32'-  assert $ Prop.monotonicL w08w16 w08 w08' w16 w16'-  assert $ Prop.monotonicL w08i08 w08 w08' i08 i08'+  assert $ Prop.idempotentL w16nat w16 nat -  assert $ Prop.idempotentL w64nat w64 nat-  assert $ Prop.idempotentL w64i64 w64 i64+  assert $ Prop.adjointL w32nat w32 nat+  assert $ Prop.closedL w32nat w32+  assert $ Prop.kernelL w32nat nat+  assert $ Prop.monotonicL w32nat w32 w32' nat nat'   assert $ Prop.idempotentL w32nat w32 nat-  assert $ Prop.idempotentL w32w64 w32 w64-  assert $ Prop.idempotentL w32i32 w32 i32-  assert $ Prop.idempotentL w16nat w16 nat-  assert $ Prop.idempotentL w16w64 w16 w64-  assert $ Prop.idempotentL w16w32 w16 w32-  assert $ Prop.idempotentL w16i16 w16 i16-  assert $ Prop.idempotentL w08nat w08 nat-  assert $ Prop.idempotentL w08w64 w08 w64-  assert $ Prop.idempotentL w08w32 w08 w32-  assert $ Prop.idempotentL w08w16 w08 w16-  assert $ Prop.idempotentL w08i08 w08 i08++  assert $ Prop.adjointL w64nat w64 nat+  assert $ Prop.closedL w64nat w64+  assert $ Prop.kernelL w64nat nat+  assert $ Prop.monotonicL w64nat w64 w64' nat nat'+  assert $ Prop.idempotentL w64nat w64 nat++  assert $ Prop.adjointL wxxnat wxx nat+  assert $ Prop.closedL wxxnat wxx+  assert $ Prop.kernelL wxxnat nat+  assert $ Prop.monotonicL wxxnat wxx wxx' nat nat'+  assert $ Prop.idempotentL wxxnat wxx nat+  +  assert $ Prop.adjointL i08nat i08 nat+  assert $ Prop.closedL i08nat i08+  assert $ Prop.kernelL i08nat nat+  assert $ Prop.monotonicL i08nat i08 i08' nat nat'+  assert $ Prop.idempotentL i08nat i08 nat++  assert $ Prop.adjointL i16nat i16 nat+  assert $ Prop.closedL i16nat i16+  assert $ Prop.kernelL i16nat nat+  assert $ Prop.monotonicL i16nat i16 i16' nat nat'+  assert $ Prop.idempotentL i16nat i16 nat++  assert $ Prop.adjointL i32nat i32 nat+  assert $ Prop.closedL i32nat i32+  assert $ Prop.kernelL i32nat nat+  assert $ Prop.idempotentL i32nat i32 nat+  assert $ Prop.monotonicL i32nat i32 i32' nat nat'++  assert $ Prop.adjointL i64nat i64 nat+  assert $ Prop.closedL i64nat i64+  assert $ Prop.kernelL i64nat nat+  assert $ Prop.idempotentL i64nat i64 nat+  assert $ Prop.monotonicL i64nat i64 i64' nat nat'++  assert $ Prop.adjointL ixxnat ixx nat+  assert $ Prop.closedL ixxnat ixx+  assert $ Prop.kernelL ixxnat nat+  assert $ Prop.idempotentL ixxnat ixx nat+  assert $ Prop.monotonicL ixxnat ixx ixx' nat nat'++  assert $ Prop.adjointL intnat int nat+  assert $ Prop.closedL intnat int+  assert $ Prop.kernelL intnat nat+  assert $ Prop.idempotentL intnat int nat+  assert $ Prop.monotonicL intnat int int' nat nat'+  tests :: IO Bool tests = checkParallel $$(discover)
test/Test/Data/Lattice.hs view
@@ -2,18 +2,16 @@ {-# LANGUAGE DataKinds #-} module Test.Data.Lattice where -import Data.Connection import Data.Lattice import Data.Connection.Property import Data.Lattice.Property-import Data.Order import Test.Data.Connection  import Hedgehog import qualified Hedgehog.Gen as G -prop_heytingL :: Property-prop_heytingL = withTests 1000 . property $ do+prop_coheyting :: Property+prop_coheyting = withTests 1000 . property $ do   b1 <- forAll G.bool   b2 <- forAll G.bool   b3 <- forAll G.bool@@ -23,15 +21,12 @@   w1 <- forAll $ G.integral (ri @Word)   w2 <- forAll $ G.integral (ri @Word)   w3 <- forAll $ G.integral (ri @Word)-  f1 <- forAll f32-  f2 <- forAll f32-  f3 <- forAll f32 -  assert $ adjointL (heyting b3) b1 b2-  assert $ closedL (heyting b3) b1-  assert $ kernelL (heyting b3) b2-  assert $ monotonicL (heyting b3) b1 b2 b3 b2-  assert $ idempotentL (heyting b3) b1 b2+  assert $ adjointL (algebra b3) b1 b2+  assert $ closedL (algebra b3) b1+  assert $ kernelL (algebra b3) b2+  assert $ monotonicL (algebra b3) b1 b2 b3 b2+  assert $ idempotentL (algebra b3) b1 b2    assert $ adjointL booleanL b1 b2   assert $ closedL booleanL b1@@ -39,32 +34,32 @@   assert $ monotonicL booleanL b1 b2 b3 b2   assert $ idempotentL booleanL b1 b3   -  assert $ heytingL1 b1 b2 b3-  assert $ heytingL2 b1 b2 b3-  assert $ heytingL3 b1 b2 b3-  assert $ heytingL4 b1 b2 b3-  assert $ heytingL5 b1 b2 b3-  assert $ heytingL6 b1 b2-  assert $ heytingL7 b1 b2-  assert $ heytingL8 b1-  assert $ heytingL9 b1 b2-  assert $ heytingL10 b1 b2-  assert $ heytingL11 b1 b2-  assert $ heytingL12 b1 b2-  assert $ heytingL13 b1 b2-  assert $ heytingL14 b1-  assert $ heytingL15 b1-  assert $ heytingL16 b1-  assert $ heytingL17 b1-  assert $ heytingL18 b1-  assert $ heytingL19 b1 b2-  assert $ heytingL20 b1 b2+  assert $ coheyting1 b1 b2 b3+  assert $ coheyting2 b1 b2 b3+  assert $ coheyting3 b1 b2 b3+  assert $ coheyting4 b1 b2 b3+  assert $ coheyting5 b1 b2 b3+  assert $ coheyting6 b1 b2+  assert $ coheyting7 b1 b2+  assert $ coheyting8 b1+  assert $ coheyting9 b1 b2+  assert $ coheyting10 b1 b2+  assert $ coheyting11 b1 b2+  assert $ coheyting12 b1 b2+  assert $ coheyting13 b1 b2+  assert $ coheyting14 b1+  assert $ coheyting15 b1+  assert $ coheyting16 b1+  assert $ coheyting17 b1+  assert $ coheyting18 b1+  assert $ coheyting19 b1 b2+  assert $ coheyting20 b1 b2 -  assert $ adjointL (heyting o3) o1 o2-  assert $ closedL (heyting o3) o1-  assert $ kernelL (heyting o3) o2-  assert $ monotonicL (heyting o3) o1 o2 o3 o2-  assert $ idempotentL (heyting o3) o1 o2+  assert $ adjointL (algebra o3) o1 o2+  assert $ closedL (algebra o3) o1+  assert $ kernelL (algebra o3) o2+  assert $ monotonicL (algebra o3) o1 o2 o3 o2+  assert $ idempotentL (algebra o3) o1 o2    assert $ adjointL booleanL o1 o2   assert $ closedL booleanL o1@@ -72,32 +67,32 @@   assert $ monotonicL booleanL o1 o2 o3 o2   assert $ idempotentL booleanL o1 o3 -  assert $ heytingL1 o1 o2 o3-  assert $ heytingL2 o1 o2 o3-  assert $ heytingL3 o1 o2 o3-  assert $ heytingL4 o1 o2 o3-  assert $ heytingL5 o1 o2 o3-  assert $ heytingL6 o1 o2-  assert $ heytingL7 o1 o2-  assert $ heytingL8 o1-  assert $ heytingL9 o1 o2-  assert $ heytingL10 o1 o2-  assert $ heytingL11 o1 o2-  assert $ heytingL12 o1 o2-  assert $ heytingL13 o1 o2-  assert $ heytingL14 o1-  assert $ heytingL15 o1-  assert $ heytingL16 o1-  assert $ heytingL17 o1-  assert $ heytingL18 o1-  assert $ heytingL19 o1 o2-  assert $ heytingL20 o1 o2+  assert $ coheyting1 o1 o2 o3+  assert $ coheyting2 o1 o2 o3+  assert $ coheyting3 o1 o2 o3+  assert $ coheyting4 o1 o2 o3+  assert $ coheyting5 o1 o2 o3+  assert $ coheyting6 o1 o2+  assert $ coheyting7 o1 o2+  assert $ coheyting8 o1+  assert $ coheyting9 o1 o2+  assert $ coheyting10 o1 o2+  assert $ coheyting11 o1 o2+  assert $ coheyting12 o1 o2+  assert $ coheyting13 o1 o2+  assert $ coheyting14 o1+  assert $ coheyting15 o1+  assert $ coheyting16 o1+  assert $ coheyting17 o1+  assert $ coheyting18 o1+  assert $ coheyting19 o1 o2+  assert $ coheyting20 o1 o2 -  assert $ adjointL (heyting w3) w1 w2-  assert $ closedL (heyting w3) w1-  assert $ kernelL (heyting w3) w2-  assert $ monotonicL (heyting w3) w1 w2 w3 w2-  assert $ idempotentL (heyting w3) w1 w2+  assert $ adjointL (algebra w3) w1 w2+  assert $ closedL (algebra w3) w1+  assert $ kernelL (algebra w3) w2+  assert $ monotonicL (algebra w3) w1 w2 w3 w2+  assert $ idempotentL (algebra w3) w1 w2    assert $ adjointL booleanL w1 w2   assert $ closedL booleanL w1@@ -105,29 +100,29 @@   assert $ monotonicL booleanL w1 w2 w3 w2   assert $ idempotentL booleanL w1 w3 -  assert $ heytingL1 w1 w2 w3-  assert $ heytingL2 w1 w2 w3-  assert $ heytingL3 w1 w2 w3-  assert $ heytingL4 w1 w2 w3-  assert $ heytingL5 w1 w2 w3-  assert $ heytingL6 w1 w2-  assert $ heytingL7 w1 w2-  assert $ heytingL8 w1-  assert $ heytingL9 w1 w2-  assert $ heytingL10 w1 w2-  assert $ heytingL11 w1 w2-  assert $ heytingL12 w1 w2-  assert $ heytingL13 w1 w2-  assert $ heytingL14 w1-  assert $ heytingL15 w1-  assert $ heytingL16 w1-  assert $ heytingL17 w1-  assert $ heytingL18 w1-  assert $ heytingL19 w1 w2-  assert $ heytingL20 w1 w2+  assert $ coheyting1 w1 w2 w3+  assert $ coheyting2 w1 w2 w3+  assert $ coheyting3 w1 w2 w3+  assert $ coheyting4 w1 w2 w3+  assert $ coheyting5 w1 w2 w3+  assert $ coheyting6 w1 w2+  assert $ coheyting7 w1 w2+  assert $ coheyting8 w1+  assert $ coheyting9 w1 w2+  assert $ coheyting10 w1 w2+  assert $ coheyting11 w1 w2+  assert $ coheyting12 w1 w2+  assert $ coheyting13 w1 w2+  assert $ coheyting14 w1+  assert $ coheyting15 w1+  assert $ coheyting16 w1+  assert $ coheyting17 w1+  assert $ coheyting18 w1+  assert $ coheyting19 w1 w2+  assert $ coheyting20 w1 w2 -prop_heytingR :: Property-prop_heytingR = withTests 1000 . property $ do+prop_heyting :: Property+prop_heyting = withTests 1000 . property $ do   b1 <- forAll G.bool   b2 <- forAll G.bool   b3 <- forAll G.bool@@ -138,11 +133,11 @@   w2 <- forAll $ G.integral (ri @Word)   w3 <- forAll $ G.integral (ri @Word) -  assert $ adjointR (heyting b3) b1 b2-  assert $ closedR (heyting b3) b1-  assert $ kernelR (heyting b3) b2-  assert $ monotonicR (heyting b3) b1 b2 b3 b2-  assert $ idempotentR (heyting b3) b1 b2+  assert $ adjointR (algebra b3) b1 b2+  assert $ closedR (algebra b3) b1+  assert $ kernelR (algebra b3) b2+  assert $ monotonicR (algebra b3) b1 b2 b3 b2+  assert $ idempotentR (algebra b3) b1 b2      assert $ adjointR booleanR b1 b2   assert $ closedR booleanR b1@@ -150,30 +145,30 @@   assert $ monotonicR booleanR b1 b2 b3 b2   assert $ idempotentR booleanR b1 b3 -  assert $ heytingR0 b1 b2 b3-  assert $ heytingR1 b1 b2 b3-  assert $ heytingR2 b1 b2 b3-  assert $ heytingR3 b1 b2 b3-  assert $ heytingR4 b1 b2 b3-  assert $ heytingR5 b1 b2 b3-  assert $ heytingR6 b1 b2-  assert $ heytingR7 b1 b2-  assert $ heytingR8 b1-  assert $ heytingR9 b1 b2-  assert $ heytingR10 b1 b2-  assert $ heytingR11 b1 b2-  assert $ heytingR12 b1 b2-  assert $ heytingR13 b1 b2-  assert $ heytingR14 b1-  assert $ heytingR15 b1-  assert $ heytingR16 b1-  assert $ heytingR17 b1+  assert $ heyting0 b1 b2 b3+  assert $ heyting1 b1 b2 b3+  assert $ heyting2 b1 b2 b3+  assert $ heyting3 b1 b2 b3+  assert $ heyting4 b1 b2 b3+  assert $ heyting5 b1 b2 b3+  assert $ heyting6 b1 b2+  assert $ heyting7 b1 b2+  assert $ heyting8 b1+  assert $ heyting9 b1 b2+  assert $ heyting10 b1 b2+  assert $ heyting11 b1 b2+  assert $ heyting12 b1 b2+  assert $ heyting13 b1 b2+  assert $ heyting14 b1+  assert $ heyting15 b1+  assert $ heyting16 b1+  assert $ heyting17 b1 -  assert $ adjointR (heyting o3) o1 o2-  assert $ closedR (heyting o3) o1-  assert $ kernelR (heyting o3) o2-  assert $ monotonicR (heyting o3) o1 o2 o3 o2-  assert $ idempotentR (heyting o3) o1 o2+  assert $ adjointR (algebra o3) o1 o2+  assert $ closedR (algebra o3) o1+  assert $ kernelR (algebra o3) o2+  assert $ monotonicR (algebra o3) o1 o2 o3 o2+  assert $ idempotentR (algebra o3) o1 o2    assert $ adjointR booleanR o1 o2   assert $ closedR booleanR o1@@ -181,30 +176,30 @@   assert $ monotonicR booleanR o1 o2 o3 o2   assert $ idempotentR booleanR o1 o3 -  assert $ heytingR0 o1 o2 o3-  assert $ heytingR1 o1 o2 o3-  assert $ heytingR2 o1 o2 o3-  assert $ heytingR3 o1 o2 o3-  assert $ heytingR4 o1 o2 o3-  assert $ heytingR5 o1 o2 o3-  assert $ heytingR6 o1 o2-  assert $ heytingR7 o1 o2-  assert $ heytingR8 o1-  assert $ heytingR9 o1 o2-  assert $ heytingR10 o1 o2-  assert $ heytingR11 o1 o2-  assert $ heytingR12 o1 o2-  assert $ heytingR13 o1 o2-  assert $ heytingR14 o1-  assert $ heytingR15 o1-  assert $ heytingR16 o1-  assert $ heytingR17 o1+  assert $ heyting0 o1 o2 o3+  assert $ heyting1 o1 o2 o3+  assert $ heyting2 o1 o2 o3+  assert $ heyting3 o1 o2 o3+  assert $ heyting4 o1 o2 o3+  assert $ heyting5 o1 o2 o3+  assert $ heyting6 o1 o2+  assert $ heyting7 o1 o2+  assert $ heyting8 o1+  assert $ heyting9 o1 o2+  assert $ heyting10 o1 o2+  assert $ heyting11 o1 o2+  assert $ heyting12 o1 o2+  assert $ heyting13 o1 o2+  assert $ heyting14 o1+  assert $ heyting15 o1+  assert $ heyting16 o1+  assert $ heyting17 o1 -  assert $ adjointR (heyting w3) w1 w2-  assert $ closedR (heyting w3) w1-  assert $ kernelR (heyting w3) w2-  assert $ monotonicR (heyting w3) w1 w2 w3 w2-  assert $ idempotentR (heyting w3) w1 w2+  assert $ adjointR (algebra w3) w1 w2+  assert $ closedR (algebra w3) w1+  assert $ kernelR (algebra w3) w2+  assert $ monotonicR (algebra w3) w1 w2 w3 w2+  assert $ idempotentR (algebra w3) w1 w2      assert $ adjointR booleanR w1 w2   assert $ closedR booleanR w1@@ -212,24 +207,24 @@   assert $ monotonicR booleanR w1 w2 w3 w2   assert $ idempotentR booleanR w1 w3 -  assert $ heytingR0 w1 w2 w3-  assert $ heytingR1 w1 w2 w3-  assert $ heytingR2 w1 w2 w3-  assert $ heytingR3 w1 w2 w3-  assert $ heytingR4 w1 w2 w3-  assert $ heytingR5 w1 w2 w3-  assert $ heytingR6 w1 w2-  assert $ heytingR7 w1 w2-  assert $ heytingR8 w1-  assert $ heytingR9 w1 w2-  assert $ heytingR10 w1 w2-  assert $ heytingR11 w1 w2-  assert $ heytingR12 w1 w2-  assert $ heytingR13 w1 w2-  assert $ heytingR14 w1-  assert $ heytingR15 w1-  assert $ heytingR16 w1-  assert $ heytingR17 w1+  assert $ heyting0 w1 w2 w3+  assert $ heyting1 w1 w2 w3+  assert $ heyting2 w1 w2 w3+  assert $ heyting3 w1 w2 w3+  assert $ heyting4 w1 w2 w3+  assert $ heyting5 w1 w2 w3+  assert $ heyting6 w1 w2+  assert $ heyting7 w1 w2+  assert $ heyting8 w1+  assert $ heyting9 w1 w2+  assert $ heyting10 w1 w2+  assert $ heyting11 w1 w2+  assert $ heyting12 w1 w2+  assert $ heyting13 w1 w2+  assert $ heyting14 w1+  assert $ heyting15 w1+  assert $ heyting16 w1+  assert $ heyting17 w1  prop_symmetric :: Property prop_symmetric = withTests 1000 . property $ do
+ test/doctest.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE CPP #-}++import Test.DocTest+import Prelude (IO)++main :: IO ()+main =+    doctest+        [ "-isrc"+        , "src/Data/Connection.hs"+        , "src/Data/Connection/Conn.hs"+        , "src/Data/Connection/Class.hs"+        , "src/Data/Connection/Float.hs"+        ]
test/test.hs view
@@ -1,31 +1,32 @@ import Control.Monad import System.Exit (exitFailure)-import System.IO (BufferMode(..), hSetBuffering, stdout, stderr)+import System.IO (BufferMode (..), hSetBuffering, stderr, stdout) -import qualified Test.Data.Order as P-import qualified Test.Data.Lattice as L import qualified Test.Data.Connection as C-import qualified Test.Data.Connection.Int as CI-import qualified Test.Data.Connection.Word as CW import qualified Test.Data.Connection.Float as CF+import qualified Test.Data.Connection.Int as CI import qualified Test.Data.Connection.Ratio as CR+import qualified Test.Data.Connection.Word as CW+import qualified Test.Data.Lattice as L+import qualified Test.Data.Order as P  tests :: IO [Bool]-tests = sequence -  [   P.tests-    , L.tests-    , C.tests-    , CI.tests-    , CW.tests-    , CF.tests-    , CR.tests-  ]+tests =+    sequence+        [ P.tests+        , L.tests+        , C.tests+        , CI.tests+        , CW.tests+        , CF.tests+        , CR.tests+        ]  main :: IO () main = do-  hSetBuffering stdout LineBuffering-  hSetBuffering stderr LineBuffering+    hSetBuffering stdout LineBuffering+    hSetBuffering stderr LineBuffering -  results <- tests+    results <- tests -  unless (and results) exitFailure+    unless (and results) exitFailure