packages feed

connections 0.2.0 → 0.3.0

raw patch · 16 files changed

+1562/−1000 lines, 16 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- 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: L :: Kan
- Data.Connection.Class: R :: Kan
- Data.Connection.Class: ceiling :: Left a b => a -> b
- Data.Connection.Class: ceiling1 :: Left a b => (a -> a) -> b -> b
- Data.Connection.Class: ceiling2 :: Left a b => (a -> a -> a) -> b -> b -> b
- Data.Connection.Class: choice :: Conn k a b -> Conn k c d -> Conn k (Either a c) (Either b d)
- Data.Connection.Class: connL :: Left a b => ConnL a b
- Data.Connection.Class: connR :: Right a b => ConnR a b
- Data.Connection.Class: data Conn (k :: Kan) a b
- Data.Connection.Class: data Kan
- Data.Connection.Class: embed :: Conn k a b -> b -> a
- Data.Connection.Class: embedL :: Left a b => b -> a
- Data.Connection.Class: embedR :: Right a b => b -> a
- Data.Connection.Class: floor :: Right a b => a -> b
- Data.Connection.Class: floor1 :: Right a b => (a -> a) -> b -> b
- Data.Connection.Class: floor2 :: Right a b => (a -> a -> a) -> b -> b -> b
- 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: 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: pattern Conn :: (a -> b) -> (b -> a) -> (a -> b) -> Conn k a b
- Data.Connection.Class: pattern ConnL :: (a -> b) -> (b -> a) -> ConnL a b
- Data.Connection.Class: pattern ConnR :: (b -> a) -> (a -> b) -> ConnR a b
- 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: strong :: Conn k a b -> Conn k c d -> Conn k (a, c) (b, d)
- 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 ConnExtended a b = Triple a (Extended b)
- Data.Connection.Class: type ConnK a b = forall k. Conn k a b
- Data.Connection.Class: type ConnL = Conn 'L
- Data.Connection.Class: type ConnR = Conn 'R
- 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: idealWith :: Preorder b => ConnR a b -> a -> b -> Bool
- 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: swapL :: ConnR a b -> ConnL b a
- Data.Connection.Conn: swapR :: ConnL a b -> ConnR b a
- 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.Property: antitone :: Rel r Bool -> Rel s Bool -> (r -> s) -> r -> r -> Bool
- Data.Connection.Ratio: shiftd :: Num a => a -> Ratio a -> Ratio a
- Data.Lattice: instance Data.Lattice.Boolean GHC.Types.Ordering
- Data.Order: [getDown] :: Down a -> a
+ Data.Connection.Class: (/\) :: Right (a, a) a => a -> a -> a
+ Data.Connection.Class: (\/) :: Left (a, a) a => a -> a -> a
+ Data.Connection.Class: choose :: Conn k c a -> Conn k c b -> Conn k c (Either a b)
+ Data.Connection.Class: divide :: Connection k (c, c) c => Conn k a c -> Conn k b c -> Conn k (a, b) c
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Integer.Type.Integer (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ 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.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended GHC.Natural.Natural)
+ 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.Double (Data.Order.Extended.Extended GHC.Types.Word)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended GHC.Word.Word16)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended GHC.Word.Word32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended GHC.Word.Word64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended GHC.Word.Word8)
+ 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.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Natural.Natural)
+ 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.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Types.Word)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Word.Word16)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Word.Word32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Word.Word64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Word.Word8)
+ Data.Connection.Class: instance Data.Connection.Class.Connection k (Data.Fixed.Fixed e, Data.Fixed.Fixed e) (Data.Fixed.Fixed e)
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Centi Data.Fixed.Deci
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Centi Data.Fixed.Uni
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Deci Data.Fixed.Uni
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Micro Data.Fixed.Centi
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Micro Data.Fixed.Deci
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Micro Data.Fixed.Milli
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Micro Data.Fixed.Uni
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Milli Data.Fixed.Centi
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Milli Data.Fixed.Deci
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Milli Data.Fixed.Uni
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Nano Data.Fixed.Centi
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Nano Data.Fixed.Deci
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Nano Data.Fixed.Micro
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Nano Data.Fixed.Milli
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Nano Data.Fixed.Uni
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Pico Data.Fixed.Centi
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Pico Data.Fixed.Deci
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Pico Data.Fixed.Micro
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Pico Data.Fixed.Milli
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Pico Data.Fixed.Nano
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Fixed.Pico Data.Fixed.Uni
+ Data.Connection.Class: instance Data.Fixed.HasResolution prec => Data.Connection.Class.Connection k GHC.Real.Rational (Data.Order.Extended.Extended (Data.Fixed.Fixed prec))
+ Data.Connection.Class: instance Data.Fixed.HasResolution res => Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended (Data.Fixed.Fixed res))
+ Data.Connection.Class: instance Data.Fixed.HasResolution res => Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended (Data.Fixed.Fixed res))
+ Data.Connection.Class: left :: Left a b => ConnL a b
+ Data.Connection.Class: right :: Right a b => ConnR a b
+ Data.Connection.Conn: Down :: a -> Down a
+ Data.Connection.Conn: ceiling :: ConnL a b -> a -> b
+ Data.Connection.Conn: ceiling1 :: ConnL a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: ceiling2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: connL :: ConnR a b -> ConnL b a
+ Data.Connection.Conn: connR :: ConnL a b -> ConnR b a
+ Data.Connection.Conn: filterL :: Preorder b => ConnL a b -> a -> b -> Bool
+ Data.Connection.Conn: filterR :: Preorder b => ConnR a b -> a -> b -> Bool
+ Data.Connection.Conn: floor :: ConnR a b -> a -> b
+ Data.Connection.Conn: floor1 :: ConnR a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: floor2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: infixr 5 `join`
+ Data.Connection.Conn: infixr 6 `meet`
+ Data.Connection.Conn: join :: ConnL (a, a) b -> a -> a -> b
+ Data.Connection.Conn: mapped :: Functor f => Conn k a b -> Conn k (f a) (f b)
+ Data.Connection.Conn: meet :: ConnR (a, a) b -> a -> a -> b
+ Data.Connection.Conn: newtype Down a
+ Data.Connection.Conn: round :: (Num a, Preorder a) => (forall k. Conn k a b) -> a -> b
+ Data.Connection.Conn: round1 :: (Num a, Preorder a) => (forall k. Conn k a b) -> (a -> a) -> b -> b
+ Data.Connection.Conn: round2 :: (Num a, Preorder a) => (forall k. Conn k a b) -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: truncate :: (Num a, Preorder a) => (forall k. Conn k a b) -> a -> b
+ Data.Connection.Conn: truncate1 :: (Num a, Preorder a) => (forall k. Conn k a b) -> (a -> a) -> b -> b
+ Data.Connection.Conn: truncate2 :: (Num a, Preorder a) => (forall k. Conn k a b) -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Fixed: MkFixed :: Integer -> Fixed a
+ Data.Connection.Fixed: class HasResolution a
+ Data.Connection.Fixed: f01f00 :: Conn k Deci Uni
+ Data.Connection.Fixed: f02f00 :: Conn k Centi Uni
+ Data.Connection.Fixed: f02f01 :: Conn k Centi Deci
+ Data.Connection.Fixed: f03f00 :: Conn k Milli Uni
+ Data.Connection.Fixed: f03f01 :: Conn k Milli Deci
+ Data.Connection.Fixed: f03f02 :: Conn k Milli Centi
+ Data.Connection.Fixed: f06f00 :: Conn k Micro Uni
+ Data.Connection.Fixed: f06f01 :: Conn k Micro Deci
+ Data.Connection.Fixed: f06f02 :: Conn k Micro Centi
+ Data.Connection.Fixed: f06f03 :: Conn k Micro Milli
+ Data.Connection.Fixed: f09f00 :: Conn k Nano Uni
+ Data.Connection.Fixed: f09f01 :: Conn k Nano Deci
+ Data.Connection.Fixed: f09f02 :: Conn k Nano Centi
+ Data.Connection.Fixed: f09f03 :: Conn k Nano Milli
+ Data.Connection.Fixed: f09f06 :: Conn k Nano Micro
+ Data.Connection.Fixed: f12f00 :: Conn k Pico Uni
+ Data.Connection.Fixed: f12f01 :: Conn k Pico Deci
+ Data.Connection.Fixed: f12f02 :: Conn k Pico Centi
+ Data.Connection.Fixed: f12f03 :: Conn k Pico Milli
+ Data.Connection.Fixed: f12f06 :: Conn k Pico Micro
+ Data.Connection.Fixed: f12f09 :: Conn k Pico Nano
+ Data.Connection.Fixed: newtype Fixed a
+ Data.Connection.Fixed: resolution :: HasResolution a => p a -> Integer
+ Data.Connection.Fixed: shiftf :: Integer -> Fixed a -> Fixed a
+ Data.Connection.Fixed: showFixed :: HasResolution a => Bool -> Fixed a -> String
+ Data.Connection.Fixed: type Centi = Fixed E2
+ Data.Connection.Fixed: type Deci = Fixed E1
+ Data.Connection.Fixed: type Micro = Fixed E6
+ Data.Connection.Fixed: type Milli = Fixed E3
+ Data.Connection.Fixed: type Nano = Fixed E9
+ Data.Connection.Fixed: type Pico = Fixed E12
+ Data.Connection.Fixed: type Uni = Fixed E0
+ Data.Connection.Float: eps32 :: Float -> Float
+ Data.Connection.Float: eps64 :: Double -> Double
+ Data.Connection.Float: f32i32 :: Conn 'L Float (Extended Int32)
+ Data.Connection.Float: f32i64 :: Conn 'L Float (Extended Int64)
+ Data.Connection.Float: f32int :: Conn 'L Float (Extended Integer)
+ Data.Connection.Float: f32ixx :: Conn 'L Float (Extended Int)
+ Data.Connection.Float: f64i64 :: Conn 'L Double (Extended Int64)
+ Data.Connection.Float: f64int :: Conn 'L Double (Extended Integer)
+ Data.Connection.Float: f64ixx :: Conn 'L Double (Extended Int)
+ Data.Connection.Ratio: ratfix :: forall e k. HasResolution e => Conn k Rational (Extended (Fixed e))
+ Data.Connection.Ratio: shiftr :: Num a => a -> Ratio a -> Ratio a
+ Data.Order: instance Data.Order.Preorder (Data.Fixed.Fixed e)
- Data.Connection.Class: infixr 3 \|/
+ Data.Connection.Class: infixr 3 `choose`
- Data.Connection.Class: infixr 4 /|\
+ Data.Connection.Class: infixr 4 `divide`
- Data.Connection.Class: infixr 5 `join`
+ Data.Connection.Class: infixr 5 \/
- Data.Connection.Class: infixr 6 `meet`
+ Data.Connection.Class: infixr 6 /\
- Data.Connection.Class: type Left = Connection 'L
+ Data.Connection.Class: type Left = Connection 'L
- Data.Connection.Class: type Right = Connection 'R
+ 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: (<<<) :: 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: (>>>) :: Category cat => cat a b -> cat b c -> cat a c
- Data.Connection.Conn: half :: (Num a, Preorder a) => ConnK a b -> a -> Maybe Ordering
+ Data.Connection.Conn: half :: (Num a, Preorder a) => (forall k. Conn k a b) -> a -> Maybe Ordering
- Data.Connection.Conn: lower :: ConnR a b -> a -> a
+ Data.Connection.Conn: lower :: ConnR a b -> b -> a
- Data.Connection.Conn: midpoint :: Fractional a => ConnK a b -> a -> a
+ Data.Connection.Conn: midpoint :: Fractional a => (forall k. Conn k a b) -> a -> a
- 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.Conn: upper :: ConnL a b -> a -> a
+ Data.Connection.Conn: upper :: ConnL a b -> b -> a
- Data.Connection.Int: i08i16 :: ConnL Int8 (Maybe Int16)
+ Data.Connection.Int: i08i16 :: Conn 'L Int8 (Maybe Int16)
- Data.Connection.Int: i08i32 :: ConnL Int8 (Maybe Int32)
+ Data.Connection.Int: i08i32 :: Conn 'L Int8 (Maybe Int32)
- Data.Connection.Int: i08i64 :: ConnL Int8 (Maybe Int64)
+ Data.Connection.Int: i08i64 :: Conn 'L Int8 (Maybe Int64)
- Data.Connection.Int: i08int :: ConnL Int8 (Maybe Integer)
+ Data.Connection.Int: i08int :: Conn 'L Int8 (Maybe Integer)
- Data.Connection.Int: i08ixx :: ConnL Int8 (Maybe Int)
+ Data.Connection.Int: i08ixx :: Conn 'L Int8 (Maybe Int)
- Data.Connection.Int: i16i32 :: ConnL Int16 (Maybe Int32)
+ Data.Connection.Int: i16i32 :: Conn 'L Int16 (Maybe Int32)
- Data.Connection.Int: i16i64 :: ConnL Int16 (Maybe Int64)
+ Data.Connection.Int: i16i64 :: Conn 'L Int16 (Maybe Int64)
- Data.Connection.Int: i16int :: ConnL Int16 (Maybe Integer)
+ Data.Connection.Int: i16int :: Conn 'L Int16 (Maybe Integer)
- Data.Connection.Int: i16ixx :: ConnL Int16 (Maybe Int)
+ Data.Connection.Int: i16ixx :: Conn 'L Int16 (Maybe Int)
- Data.Connection.Int: i32i64 :: ConnL Int32 (Maybe Int64)
+ Data.Connection.Int: i32i64 :: Conn 'L Int32 (Maybe Int64)
- Data.Connection.Int: i32int :: ConnL Int32 (Maybe Integer)
+ Data.Connection.Int: i32int :: Conn 'L Int32 (Maybe Integer)
- Data.Connection.Int: i32ixx :: ConnL Int32 (Maybe Int)
+ Data.Connection.Int: i32ixx :: Conn 'L Int32 (Maybe Int)
- Data.Connection.Int: i64int :: ConnL Int64 (Maybe Integer)
+ Data.Connection.Int: i64int :: Conn 'L Int64 (Maybe Integer)
- Data.Connection.Int: ixxint :: ConnL Int (Maybe Integer)
+ Data.Connection.Int: ixxint :: Conn 'L Int (Maybe Integer)
- Data.Connection.Int: natint :: ConnL Natural (Maybe Integer)
+ Data.Connection.Int: natint :: Conn 'L Natural (Maybe Integer)
- Data.Connection.Int: w08i16 :: ConnL Word8 (Maybe Int16)
+ Data.Connection.Int: w08i16 :: Conn 'L Word8 (Maybe Int16)
- Data.Connection.Int: w08i32 :: ConnL Word8 (Maybe Int32)
+ Data.Connection.Int: w08i32 :: Conn 'L Word8 (Maybe Int32)
- Data.Connection.Int: w08i64 :: ConnL Word8 (Maybe Int64)
+ Data.Connection.Int: w08i64 :: Conn 'L Word8 (Maybe Int64)
- Data.Connection.Int: w08int :: ConnL Word8 (Maybe Integer)
+ Data.Connection.Int: w08int :: Conn 'L Word8 (Maybe Integer)
- Data.Connection.Int: w08ixx :: ConnL Word8 (Maybe Int)
+ Data.Connection.Int: w08ixx :: Conn 'L Word8 (Maybe Int)
- Data.Connection.Int: w16i32 :: ConnL Word16 (Maybe Int32)
+ Data.Connection.Int: w16i32 :: Conn 'L Word16 (Maybe Int32)
- Data.Connection.Int: w16i64 :: ConnL Word16 (Maybe Int64)
+ Data.Connection.Int: w16i64 :: Conn 'L Word16 (Maybe Int64)
- Data.Connection.Int: w16int :: ConnL Word16 (Maybe Integer)
+ Data.Connection.Int: w16int :: Conn 'L Word16 (Maybe Integer)
- Data.Connection.Int: w16ixx :: ConnL Word16 (Maybe Int)
+ Data.Connection.Int: w16ixx :: Conn 'L Word16 (Maybe Int)
- Data.Connection.Int: w32i64 :: ConnL Word32 (Maybe Int64)
+ Data.Connection.Int: w32i64 :: Conn 'L Word32 (Maybe Int64)
- Data.Connection.Int: w32int :: ConnL Word32 (Maybe Integer)
+ Data.Connection.Int: w32int :: Conn 'L Word32 (Maybe Integer)
- Data.Connection.Int: w32ixx :: ConnL Word32 (Maybe Int)
+ Data.Connection.Int: w32ixx :: Conn 'L Word32 (Maybe Int)
- Data.Connection.Int: w64int :: ConnL Word64 (Maybe Integer)
+ Data.Connection.Int: w64int :: Conn 'L Word64 (Maybe Integer)
- Data.Connection.Int: wxxint :: ConnL Word (Maybe Integer)
+ Data.Connection.Int: wxxint :: Conn 'L Word (Maybe Integer)
- Data.Connection.Property: adjoint :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool
+ Data.Connection.Property: adjoint :: (Preorder a, Preorder b) => (forall k. Conn k a b) -> a -> b -> Bool
- Data.Connection.Property: closed :: (Preorder a, Preorder b) => ConnK a b -> a -> Bool
+ Data.Connection.Property: closed :: (Preorder a, Preorder b) => (forall k. Conn k a b) -> a -> Bool
- Data.Connection.Property: idempotent :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool
+ Data.Connection.Property: idempotent :: (Preorder a, Preorder b) => (forall k. Conn k a b) -> a -> b -> Bool
- Data.Connection.Property: kernel :: (Preorder a, Preorder b) => ConnK a b -> b -> Bool
+ Data.Connection.Property: kernel :: (Preorder a, Preorder b) => (forall k. Conn k a b) -> b -> Bool
- Data.Connection.Property: monotonic :: (Preorder a, Preorder b) => ConnK a b -> a -> a -> b -> b -> Bool
+ Data.Connection.Property: monotonic :: (Preorder a, Preorder b) => (forall k. Conn k a b) -> a -> a -> b -> b -> Bool
- Data.Lattice: (//) :: Algebra 'R a => a -> a -> a
+ Data.Lattice: (//) :: Algebra 'R a => a -> a -> a
- Data.Lattice: (\\) :: Algebra 'L a => a -> a -> a
+ Data.Lattice: (\\) :: Algebra 'L a => a -> a -> a
- Data.Lattice: equiv :: Algebra 'L a => a -> a -> a
+ Data.Lattice: equiv :: Algebra 'L a => a -> a -> a
- Data.Lattice: iff :: Algebra 'R a => a -> a -> a
+ Data.Lattice: iff :: Algebra 'R a => a -> a -> a
- Data.Lattice: type Coheyting a = (Lattice a, Algebra 'L a)
+ Data.Lattice: type Coheyting a = (Lattice a, Algebra 'L a)
- Data.Lattice: type Heyting a = (Lattice a, Algebra 'R a)
+ Data.Lattice: type Heyting a = (Lattice a, Algebra 'R a)
- Data.Lattice: type Join = Semilattice 'L
+ Data.Lattice: type Join = Semilattice 'L
- Data.Lattice: type Meet = Semilattice 'R
+ Data.Lattice: type Meet = Semilattice 'R

Files

connections.cabal view
@@ -1,7 +1,7 @@ name:                connections-version:             0.2.0+version:             0.3.0 synopsis:            Orders, Galois connections, and lattices.-description:         A library for order manipulation using Galois connections.+description:         A library for order manipulation using Galois connections. See the README for a brief overview. homepage:            https://github.com/cmk/connections license:             BSD3 license-file:        LICENSE@@ -22,10 +22,11 @@       Data.Connection     , Data.Connection.Conn     , Data.Connection.Class+    , Data.Connection.Fixed+    , Data.Connection.Float     , Data.Connection.Int-    , Data.Connection.Word     , Data.Connection.Ratio-    , Data.Connection.Float+    , Data.Connection.Word     , Data.Connection.Property      , Data.Lattice@@ -49,6 +50,7 @@     , Test.Data.Connection     , Test.Data.Connection.Int     , Test.Data.Connection.Word+    , Test.Data.Connection.Fixed     , Test.Data.Connection.Float     , Test.Data.Connection.Ratio   build-depends:       
src/Data/Connection/Class.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE RankNTypes #-}@@ -11,71 +12,36 @@ {-# LANGUAGE ViewPatterns #-}  module Data.Connection.Class (-    -- * Conn-    Conn (),-    identity,--    -- * Connection k+    -- * Types+    Left,+    left,+    Right,+    right,     Triple,-    pattern Conn,-    ConnK,-    embed,-    extremal,++    -- * Lattices+    (\/),+    (/\),     lub,     glb,-    half,-    midpoint,-    range,-    round,-    round1,-    round2,-    truncate,-    truncate1,-    truncate2,--    -- * Connection L-    Left,-    pattern ConnL,-    ConnL,-    connL,-    embedL,+    choose,+    divide,     minimal,-    join,-    ceiling,-    ceiling1,-    ceiling2,--    -- * Connection R-    Right,-    pattern ConnR,-    ConnR,-    connR,-    embedR,     maximal,-    meet,-    floor,-    floor1,-    floor2,--    -- * Combinators-    (>>>),-    (<<<),-    (/|\),-    (\|/),-    choice,-    strong,+    extremal,      -- * Connection-    Kan (..),+    Connection (..),++    -- ** RebindableSyntax     ConnInteger,     ConnRational,-    ConnExtended,-    Connection (..), ) where  import safe Control.Category ((>>>)) import safe Data.Bool (bool) import safe Data.Connection.Conn+import safe Data.Connection.Fixed import safe Data.Connection.Float import safe Data.Connection.Int import safe Data.Connection.Ratio@@ -102,8 +68,18 @@  type Left = Connection 'L +-- | A specialization of /conn/ to left-side connections.+--+left :: Left a b => ConnL a b+left = conn @ 'L+ type Right = Connection 'R +-- | A specialization of /conn/ to right-side connections.+--+right :: Right a b => ConnR a b+right = conn @ '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) @@ -111,18 +87,16 @@ -- --  Usable in conjunction with /RebindableSyntax/: -----  > fromInteger = embedL . Just :: ConnInteger a => Integer -> a+--  > fromInteger = upper conn . 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+--  > fromRational = round conn :: 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     -- |@@ -133,64 +107,7 @@     -- (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@@ -205,8 +122,8 @@     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+    halfR = x - right (connR @a @b) x -- dist from lower bound+    halfL = left (connL @a @b) x - x -- dist from upper bound  -- | Lift a unary function over a 'Conn'. --@@ -255,112 +172,103 @@ 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+-- Lattices --------------------------------------------------------------------- --- | 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+infixr 5 \/ --- | A minimal element of a preorder.------ 'minimal' needn't be unique, but it must obey:+-- | Lattice join. ----- > x <~ minimal => x ~~ minimal-minimal :: Left () a => a-minimal = ceiling ()+-- > (\/) = curry $ lower semilattice+(\/) :: Left (a, a) a => a -> a -> a+(\/) = join conn -infixr 5 `join`+infixr 6 /\ -- comment for the parser --- | Semigroup operation on a join-lattice.-join :: Left (a, a) a => a -> a -> a-join = curry ceiling+-- | Lattice meet.+--+-- > (/\) = curry $ floor semilattice+(/\) :: Right (a, a) a => a -> a -> a+(/\) = meet conn --- | Extract the ceiling of a 'Conn' or lower half of a 'ConnL'.+-- | Least upper bound operator. ----- > ceiling @a @a = id--- > ceiling (x1 `join` a2) = ceiling x1 `join` ceiling x2+-- The order dual of 'glb'. ----- The latter law is the adjoint functor theorem for preorders.+-- >>> 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++-- | Greatest lower bound operator. ----- >>> 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+-- > 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 \/ y) /\ (y \/ z) /\ (z \/ x) --- | Lift a unary function over a 'ConnL'.-ceiling1 :: Left a b => (a -> a) -> b -> b-ceiling1 = ceilingWith1 conn+infixr 3 `choose` --- | Lift a binary function over a 'ConnL'.-ceiling2 :: Left a b => (a -> a -> a) -> b -> b -> b-ceiling2 = ceilingWith2 conn+-- | A preorder variant of 'Control.Arrow.|||'.+choose :: Conn k c a -> Conn k c b -> Conn k c (Either a b)+choose f g = Conn Left (either id id) Right >>> f `choice` g ------------------------------------------------------------------------- Connection R----------------------------------------------------------------------+infixr 4 `divide` --- | 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+-- | A preorder variant of 'Control.Arrow.&&&'.+divide :: Connection k (c, c) c => Conn k a c -> Conn k b c -> Conn k (a, b) c+divide f g = f `strong` g >>> conn --- | Extract the center of a 'ConnK' or lower half of a 'ConnR'.-embedR :: Right a b => b -> a-embedR = embed connR+-- | A minimal element of a preorder.+--+-- > x /\ minimal = minimal+-- > x \/ minimal = x+--+-- 'minimal' needn't be unique, but it must obey:+--+-- > x <~ minimal => x ~~ minimal+minimal :: Left () a => a+minimal = ceiling conn ()  -- | A maximal element of a preorder. --+-- > x /\ maximal = x+-- > x \/ maximal = maximal+-- -- '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+maximal = floor conn () --- | 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+-- | The canonical connection with a 'Bool'.+extremal :: Triple () a => Conn k a Bool+extremal = Conn f g h+  where+    g False = minimal+    g True = maximal --- | Lift a unary function over a 'ConnR'.-floor1 :: Right a b => (a -> a) -> b -> b-floor1 = floorWith1 conn+    f i+        | i ~~ minimal = False+        | otherwise = True --- | Lift a binary function over a 'ConnR'.-floor2 :: Right a b => (a -> a -> a) -> b -> b -> b-floor2 = floorWith2 conn+    h i+        | i ~~ maximal = True+        | otherwise = False  --------------------------------------------------------------------- -- Instances@@ -466,6 +374,35 @@     conn = Conn (const $ -1 :% 0) (const ()) (const $ 1 :% 0) instance Connection k (Rational, Rational) Rational where conn = latticeN5 +instance Connection k Deci Uni where conn = f01f00+instance Connection k Centi Uni where conn = f02f00+instance Connection k Milli Uni where conn = f03f00+instance Connection k Micro Uni where conn = f06f00+instance Connection k Nano Uni where conn = f09f00+instance Connection k Pico Uni where conn = f12f00++instance Connection k Centi Deci where conn = f02f01+instance Connection k Milli Deci where conn = f03f01+instance Connection k Micro Deci where conn = f06f01+instance Connection k Nano Deci where conn = f09f01+instance Connection k Pico Deci where conn = f12f01++instance Connection k Milli Centi where conn = f03f02+instance Connection k Micro Centi where conn = f06f02+instance Connection k Nano Centi where conn = f09f02+instance Connection k Pico Centi where conn = f12f02++instance Connection k Micro Milli where conn = f06f03+instance Connection k Nano Milli where conn = f09f03+instance Connection k Pico Milli where conn = f12f03++instance Connection k Nano Micro where conn = f09f06+instance Connection k Pico Micro where conn = f12f06++instance Connection k Pico Nano where conn = f12f09++instance Connection k (Fixed e, Fixed e) (Fixed e) where conn = latticeOrd+ instance Connection k () Float where conn = extremalN5 instance Connection k Double Float where conn = f64f32 instance Connection k Rational Float where conn = ratf32@@ -510,28 +447,51 @@ 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--}+    conn = c1 >>> intnat >>> natint >>> c2+      where+        c1 = Conn shiftR shiftL shiftR+        c2 = Conn (fmap shiftL) (fmap shiftR) (fmap shiftL) +        shiftR x = x + m+        shiftL x = x - m+        m = 9223372036854775808+ 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 HasResolution prec => Connection k Rational (Extended (Fixed prec)) where conn = ratfix --- | All 'Data.Int.Int08' values are exactly representable in a 'Float'.+instance Connection 'L Float (Extended Word8) where conn = f32i08 >>> mapped i08w08+instance Connection 'L Float (Extended Word16) where conn = f32i16 >>> mapped i16w16+instance Connection 'L Float (Extended Word32) where conn = f32i32 >>> mapped i32w32+instance Connection 'L Float (Extended Word64) where conn = f32i64 >>> mapped i64w64+instance Connection 'L Float (Extended Word) where conn = f32ixx >>> mapped ixxwxx+instance Connection 'L Float (Extended Natural) where conn = f32int >>> mapped intnat++-- | All 'Data.Int.Int8' 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 'L Float (Extended Int32) where conn = f32i32+instance Connection 'L Float (Extended Int64) where conn = f32i64+instance Connection 'L Float (Extended Int) where conn = f32ixx+instance Connection 'L Float (Extended Integer) where conn = f32int+instance HasResolution res => Connection 'L Float (Extended (Fixed res)) where conn = connL ratf32 >>> ratfix++instance Connection 'L Double (Extended Word8) where conn = f64i08 >>> mapped i08w08+instance Connection 'L Double (Extended Word16) where conn = f64i16 >>> mapped i16w16+instance Connection 'L Double (Extended Word32) where conn = f64i32 >>> mapped i32w32+instance Connection 'L Double (Extended Word64) where conn = f64i64 >>> mapped i64w64+instance Connection 'L Double (Extended Word) where conn = f64ixx >>> mapped ixxwxx+instance Connection 'L Double (Extended Natural) where conn = f64int >>> mapped intnat++-- | All 'Data.Int.Int8' 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'.@@ -540,6 +500,11 @@ -- | All 'Data.Int.Int32' values are exactly representable in a 'Double'. instance Connection k Double (Extended Int32) where conn = f64i32 +instance Connection 'L Double (Extended Int64) where conn = f64i64+instance Connection 'L Double (Extended Int) where conn = f64ixx+instance Connection 'L Double (Extended Integer) where conn = f64int+instance HasResolution res => Connection 'L Double (Extended (Fixed res)) where conn = connL ratf64 >>> ratfix+ instance Connection k a b => Connection k (Identity a) b where     conn = Conn runIdentity Identity runIdentity >>> conn @@ -586,19 +551,19 @@     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+    conn = ConnL (uncurry $ Map.unionWith (join conn)) 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)+    conn = ConnR fork (uncurry $ Map.intersectionWith (meet conn))  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+    conn = ConnL (uncurry $ IntMap.unionWith (join conn)) 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)+    conn = ConnR fork (uncurry $ IntMap.intersectionWith (meet conn))  -- Internal @@ -666,7 +631,7 @@ joinMaybe _ u@(Just _) = u joinMaybe Nothing Nothing = Nothing -meetMaybe :: Connection 'R (a, a) a => Maybe a -> Maybe a -> Maybe a+meetMaybe :: Right (a, a) a => Maybe a -> Maybe a -> Maybe a meetMaybe Nothing Nothing = Nothing meetMaybe Nothing _ = Nothing meetMaybe _ Nothing = Nothing@@ -679,7 +644,7 @@ joinExtended Bottom       y            = y joinExtended x            Bottom       = x -meetExtended :: Connection 'R (a, a) a => Extended a -> Extended a -> Extended a+meetExtended :: Right (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)@@ -692,7 +657,7 @@ 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 :: (Right (a, a) a, Right (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@@ -701,6 +666,6 @@ 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 :: (Right (a, a) a, Right (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
@@ -14,65 +14,66 @@     -- * Conn     Kan (..),     Conn (),-    pattern Conn,     embed,     range,     identity,--    -- * Connection k-    ConnK,-    half,-    midpoint,-    roundWith,-    roundWith1,-    roundWith2,-    truncateWith,-    truncateWith1,-    truncateWith2,+    (>>>),+    (<<<),+    mapped,+    choice,+    strong,      -- * Connection L     ConnL,     pattern ConnL,-    upL,-    downL,-    swapL,-    counit,+    connL,     upper,     upper1,     upper2,-    filterWith,-    ceilingWith,-    ceilingWith1,-    ceilingWith2,+    join,+    ceiling,+    ceiling1,+    ceiling2,      -- * Connection R     ConnR,     pattern ConnR,-    upR,-    downR,-    swapR,-    unit,+    connR,     lower,     lower1,     lower2,-    idealWith,-    floorWith,-    floorWith1,-    floorWith2,+    meet,+    floor,+    floor1,+    floor2, -    -- * Combinators-    (>>>),-    (<<<),-    choice,-    strong,+    -- * Connection k+    pattern Conn,+    half,+    midpoint,+    round,+    round1,+    round2,+    truncate,+    truncate1,+    truncate2,++    -- * Down+    upL,+    upR,+    downL,+    downR,+    filterL,+    filterR,+    Down (..), ) where -import safe Control.Arrow+import safe Control.Arrow ((&&&)) 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 (..))+import safe Prelude hiding (Ord (..), ceiling, floor, round, truncate)  -- $setup -- >>> :set -XTypeApplications@@ -85,322 +86,411 @@  -- | A data kind distinguishing the directionality of a Galois connection: ----- * /L/-tagged types are low / increasing (e.g. 'Data.Connection.Class.minimal', 'Data.Connection.Class.upper', 'Data.Connection.Class.ceiling', 'Data.Connection.Class.join')+-- * /L/-tagged types are low / increasing (e.g. 'Data.Connection.Class.minimal', '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')+-- * /R/-tagged types are high / decreasing (e.g. 'Data.Connection.Class.maximal', '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.+-- | A (chain of) Galois connections. --+-- A [Galois connection](https://en.wikipedia.org/wiki/Galois_connection) between preorders P and Q+-- is a pair of monotone maps `f :: p -> q` and `g :: q -> p` such that:+--+-- > f x <= y iff x <= g y+--+-- We say that `f` is the left or right adjoint, and `g` is the right or left adjoint of the connection.+-- -- 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)+--+-- See the /README/ file for a slightly more in-depth introduction.+data Conn (k :: Kan) a b = Conn_ (a -> (b, b)) (b -> a)  instance Category (Conn k) where     id = identity     {-# INLINE id #-} -    Galois f1 g1 . Galois f2 g2 = Galois ((fst . f1) . (fst . f2) &&& (snd . f1) . (snd . f2)) (g2 . g1)+    Conn_ f1 g1 . Conn_ f2 g2 = Conn_ ((fst . f1) . (fst . f2) &&& (snd . f1) . (snd . f2)) (g2 . g1)     {-# INLINE (.) #-} --- | Obtain a /Conn/ from an adjoint triple of monotone functions.------  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 (Galois f _) = fst . f+_1 (Conn_ 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 (Galois f _) = snd . f+_2 (Conn_ 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'.+-- | Retrieve the upper adjoint of a 'ConnL', or lower adjoint of a 'ConnR'. embed :: Conn k a b -> b -> a-embed (Galois _ g) = g+embed (Conn_ _ g) = g {-# INLINE embed #-} --- | Obtain the upper and/or lower adjoints of a connection.+-- | Retrieve the left and/or right adjoints of a connection. ----- > range c = floorWith c &&& ceilingWith c+-- > range c = floor c &&& ceiling 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+range (Conn_ f _) = f {-# INLINE range #-} +-- | The identity 'Conn'.+identity :: Conn k a a+identity = Conn_ (id &&& id) id+{-# INLINE identity #-}++-- | 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').+mapped :: Functor f => Conn k a b -> Conn k (f a) (f b)+mapped (Conn f g h) = Conn (fmap f) (fmap g) (fmap h)+{-# INLINE mapped #-}++-- | 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')+{-# 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'+{-# INLINE strong #-}+ ------------------------------------------------------------------------ ConnK+-- Conn 'L --------------------------------------------------------------------- --- | An <https://ncatlab.org/nlab/show/adjoint+triple adjoint triple> of Galois connections.+type ConnL = Conn 'L++-- | A <https://ncatlab.org/nlab/show/Galois+connection Galois connection> between two monotone functions. ----- An adjoint triple is a chain of connections of length 3:+-- A Galois connection between /f/ and /g/, written \(f \dashv g \)+-- is an adjunction in the category of preorders. ----- \(f \dashv g \dashv h \)+-- Each side of the connection may be defined in terms of the other: ----- 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.+--  \( g(x) = \sup \{y \in E \mid f(y) \leq x \} \) ----- @ 'half' t x = 'pcompare' (x - 'lower' t x) ('upper' t x - x) @+--  \( f(x) = \inf \{y \in E \mid g(y) \geq 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 #-}+-- /Caution/: /ConnL f g/ must obey \(f \dashv g \). This condition is not checked.+--+-- For further information see 'Data.Connection.Property'.+pattern ConnL :: (a -> b) -> (b -> a) -> ConnL a b+pattern ConnL f g <- (_2 &&& upper -> (f, g)) where ConnL f g = Conn_ (f &&& f) g --- | Return the midpoint of the interval containing x.+{-# COMPLETE ConnL #-}++-- | Witness to the symmetry between 'ConnL' and 'ConnR'. ----- >>> 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 #-}+-- > connL . connR = id+-- > connR . connL = id+connL :: ConnR a b -> ConnL b a+connL (ConnR f g) = ConnL f g+{-# INLINE connL #-} --- | Return the nearest value to x.+-- | Obtain the upper adjoint of a 'ConnL', or lower adjoint of a 'ConnR'.+upper :: ConnL a b -> b -> a+upper = embed+{-# INLINE upper #-}++-- | Map over a 'ConnL' from the right. ----- > roundWith identity = id+-- This is the unit of the resulting monad: ----- If x lies halfway between two finite values, then return the value--- with the larger absolute value (i.e. round away from zero).+-- > x <~ upper1 c id x ----- 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 #-}+-- >>> compare pi $ upper1 f64f32 id pi+-- LT+upper1 :: ConnL a b -> (b -> b) -> a -> a+upper1 (ConnL f g) h a = g $ h (f a)+{-# INLINE upper1 #-} --- | Lift a unary function over a 'ConnK'.------ 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 #-}+-- | Zip over a '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 #-} --- | Lift a binary function over a 'ConnK'.+infixr 5 `join`++-- | Semigroup operation on a join-semilattice.+join :: ConnL (a, a) b -> a -> a -> b+join = curry . ceiling+{-# INLINE join #-}++-- | Extract the lower half of a 'ConnL'. ----- Results are rounded to the nearest value with ties away from 0.+-- > ceiling identity = id+-- > ceiling c (x \/ y) = ceiling c x \/ ceiling c y ----- Example avoiding loss-of-precision:+-- The latter law is the adjoint functor theorem for preorders. ----- >>> 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 #-}+-- >>> Data.Connection.ceiling ratf32 (0 :% 0)+-- NaN+-- >>> Data.Connection.ceiling ratf32 (1 :% 0)+-- Infinity+-- >>> Data.Connection.ceiling ratf32 (13 :% 10)+-- 1.3000001+-- >>> Data.Connection.ceiling f64f32 pi+-- 3.1415927+ceiling :: ConnL a b -> a -> b+ceiling (ConnL f _) = f+{-# INLINE ceiling #-} --- | Truncate towards zero.+-- | Map over a 'ConnL' from the left. ----- > 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'.+-- This is the counit of the resulting comonad: ----- Results are truncated towards zero.+-- > x >~ ceiling1 c id x ----- > 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 #-}+-- >>> ceiling1 (conn @_ @() @Ordering) id LT+-- LT+-- >>> ceiling1 (conn @_ @() @Ordering) id GT+-- LT+ceiling1 :: ConnL a b -> (a -> a) -> b -> b+ceiling1 (ConnL f g) h b = f $ h (g b)+{-# INLINE ceiling1 #-} -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 #-}+-- | Zip over a 'ConnL' from the left.+ceiling2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b+ceiling2 (ConnL f g) h b1 b2 = f $ h (g b1) (g b2)+{-# INLINE ceiling2 #-}  ------------------------------------------------------------------------ ConnL+-- Conn 'R --------------------------------------------------------------------- --- | A <https://ncatlab.org/nlab/show/Galois+connection Galois connection> between two monotone functions.+type ConnR = Conn 'R++-- | A Galois connection between two monotone functions. ----- A Galois connection between /f/ and /g/, written \(f \dashv g \)--- is an adjunction in the category of preorders.+-- 'ConnR' is the mirror image of 'ConnL': ----- Each side of the connection may be defined in terms of the other:+-- > connR :: ConnL a b -> ConnR b a -----  \( g(x) = \sup \{y \in E \mid f(y) \leq x \} \)+-- If you only require one connection there is no particular reason to+-- use one version over the other. However some use cases (e.g. rounding)+-- require an adjoint triple of connections that can lower into a standard+-- connection in either of two ways. -----  \( f(x) = \inf \{y \in E \mid g(y) \geq x \} \)+-- /Caution/: /ConnR f g/ must obey \(f \dashv g \). This condition is not checked. -- -- For further information see 'Data.Connection.Property'.------ /Caution/: Monotonicity is not checked.-type ConnL = Conn 'L+pattern ConnR :: (b -> a) -> (a -> b) -> ConnR a b+pattern ConnR f g <- (lower &&& _1 -> (f, g)) where ConnR f g = Conn_ (g &&& g) f --- | A view pattern for a 'ConnL'.+{-# COMPLETE ConnR #-}++-- | Witness to the symmetry between 'ConnL' and 'ConnR'. ----- /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 = Galois (f &&& f) g+-- > connL . connR = id+-- > connR . connL = id+connR :: ConnL a b -> ConnR b a+connR (ConnL f g) = ConnR f g+{-# INLINE connR #-} -{-# COMPLETE ConnL #-}+-- | Obtain the  lower adjoint of a 'ConnR'.+lower :: ConnR a b -> b -> a+lower = embed+{-# INLINE lower #-} --- | Convert an inverted 'ConnL' to a 'ConnL'.+-- | Map over a 'ConnR' from the left. ----- > 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 a 'ConnL' to an inverted 'ConnL'.+-- This is the counit of the resulting comonad: ----- >>> upper (downL $ conn @_ @() @Ordering) (Down LT)--- Down LT--- >>> 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 #-}---- | Witness to the symmetry between 'ConnL' and 'ConnR'.+-- > x >~ lower1 c id x ----- > swapL . swapR = id--- > swapR . swapL = id-swapL :: ConnR a b -> ConnL b a-swapL (ConnR f g) = ConnL f g-{-# INLINE swapL #-}+-- >>> compare pi $ lower1 f64f32 id pi+-- GT+lower1 :: ConnR a b -> (b -> b) -> a -> a+lower1 (ConnR f g) h a = f $ h (g a)+{-# INLINE lower1 #-} --- | Reverse round trip through a 'ConnK' or 'ConnL'.+-- | Zip over a '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 #-}++infixr 6 `meet`++-- | Semigroup operation on a meet-semilattice.+meet :: ConnR (a, a) b -> a -> a -> b+meet = curry . floor+{-# INLINE meet #-}++-- | Extract the upper half of a 'ConnR' ----- This is the counit of the resulting comonad:+-- > floor identity = id+-- > floor c (x /\ y) = floor c x /\ floor c y ----- > x >~ counit c x+-- The latter law is the adjoint functor theorem for preorders. ----- >>> counit (conn @_ @() @Ordering) LT--- LT--- >>> counit (conn @_ @() @Ordering) GT--- LT-counit :: ConnL a b -> b -> b-counit c = ceilingWith1 c id-{-# INLINE counit #-}+-- >>> Data.Connection.floor ratf32 (0 :% 0)+-- NaN+-- >>> Data.Connection.floor ratf32 (1 :% 0)+-- Infinity+-- >>> Data.Connection.floor ratf32 (13 :% 10)+-- 1.3+-- >>> Data.Connection.floor f64f32 pi+-- 3.1415925+floor :: ConnR a b -> a -> b+floor (ConnR _ g) = g+{-# INLINE floor #-} --- | Round trip through a 'ConnK' or 'ConnL'.+-- | Map over a 'ConnR' from the right. ----- > upper c = upper1 c id = embed c . ceilingWith c--- > x <= upper c x+-- This is the unit of the resulting monad: ----- >>> compare pi $ upper f64f32 pi--- LT-upper :: ConnL a b -> a -> a-upper c = upper1 c id-{-# INLINE upper #-}+-- > x <~ floor1 c id x+--+-- >>> floor1 (conn @_ @() @Ordering) id LT+-- GT+-- >>> floor1 (conn @_ @() @Ordering) id GT+-- GT+floor1 :: ConnR a b -> (a -> a) -> b -> b+floor1 (ConnR f g) h b = g $ h (f b)+{-# INLINE floor1 #-} --- | 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 'ConnR' from the right.+floor2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b+floor2 (ConnR f g) h b1 b2 = g $ h (f b1) (f b2)+{-# INLINE floor2 #-} --- | 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 #-}+---------------------------------------------------------------------+-- Conn k+--------------------------------------------------------------------- --- | 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 `meet` y@ is also in /b/.+-- | An <https://ncatlab.org/nlab/show/adjoint+triple adjoint triple> of Galois connections. ----- /filterWith/ and /idealWith/ commute with /Down/:+-- An adjoint triple is a chain of connections of length 3: ----- > filterWith c a b <=> idealWith c (Down a) (Down b)+-- \(f \dashv g \dashv h \) ----- > filterWith c (Down a) (Down b) <=> idealWith c a b+-- When applied to a 'ConnL' or 'ConnR', the two functions of type @a -> b@ returned will be identical. ----- /filterWith c a/ is upward-closed for all /a/:+-- /Caution/: /Conn f g h/ must obey \(f \dashv g \dashv h\). This condition is not checked. ----- > a <= b1 && b1 <= b2 => a <= b2+-- 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 = Conn_ (h &&& f) g++{-# COMPLETE Conn #-}++-- | Determine which half of the interval between 2 representations of /a/ a particular value lies. ----- > a1 <= b && inf a2 <= b => ceiling a1 `meet` ceiling a2 <= b+-- @ 'half' c x = 'pcompare' (x - 'lower1' c 'id' x) ('upper1' c 'id' x - x) @ ----- 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 #-}+-- >>> maybe False (== EQ) $ half f64f32 (midpoint f64f32 pi)+-- True+half :: (Num a, Preorder a) => (forall k. Conn k a b) -> a -> Maybe Ordering+half c x = pcompare (x - lower1 c id x) (upper1 c id x - x)+{-# INLINE half #-} --- | Extract the left half of a 'ConnK' or 'ConnL'.+-- | Return the midpoint of the interval containing x. ----- >>> 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 #-}+-- >>> pi - midpoint f64f32 pi+-- 3.1786509424591713e-8+midpoint :: Fractional a => (forall k. Conn k a b) -> a -> a+midpoint c x = lower1 c id x / 2 + upper1 c id x / 2+{-# INLINE midpoint #-} --- | 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 #-}+-- | Return the nearest value to x.+--+-- > round identity = 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 :: (Num a, Preorder a) => (forall k. Conn k a b) -> a -> b+round c x = case half c x of+    Just GT -> ceiling c x+    Just LT -> floor c x+    _ -> truncate c x+{-# INLINE round #-} ------------------------------------------------------------------------- ConnR----------------------------------------------------------------------+-- | Lift a unary function over a 'Trip'.+--+-- Results are rounded to the nearest value with ties away from 0.+round1 :: (Num a, Preorder a) => (forall k. Conn k a b) -> (a -> a) -> b -> b+round1 c f x = round c $ f (g x) where Conn _ g _ = c+{-# INLINE round1 #-} --- | A Galois connection between two monotone functions.+-- | Lift a binary function over a 'Trip'. ----- 'ConnR' is the mirror image of 'ConnL':+-- Results are rounded to the nearest value with ties away from 0. ----- > swapR :: ConnL a b -> ConnR b a+-- Example avoiding loss-of-precision: ----- If you only require one connection there is no particular reason to--- use one version over the other.+-- >>> f x y = (x + y) - x+-- >>> maxOdd32 = 1.6777215e7+-- >>> f maxOdd32 2.0 :: Float+-- 1.0+-- >>> round2 ratf32 f maxOdd32 2.0+-- 2.0+round2 :: (Num a, Preorder a) => (forall k. Conn k a b) -> (a -> a -> a) -> b -> b -> b+round2 c f x y = round c $ f (g x) (g y) where Conn _ g _ = c+{-# INLINE round2 #-}++-- | Truncate towards zero. ----- However some use cases (e.g. rounding) require an adjoint triple--- of connections (i.e. a 'ConnK') that can lower into a standard--- connection in either of two ways.-type ConnR = Conn 'R+-- > truncate identity = id+truncate :: (Num a, Preorder a) => (forall k. Conn k a b) -> a -> b+truncate c x = if x >~ 0 then floor c x else ceiling c x+{-# INLINE truncate #-} --- | A view pattern for a 'ConnR'.+-- | Lift a unary function over a 'Trip'. ----- /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 = Galois (g &&& g) f+-- Results are truncated towards zero.+--+-- > truncate1 identity = id+truncate1 :: (Num a, Preorder a) => (forall k. Conn k a b) -> (a -> a) -> b -> b+truncate1 c f x = truncate c $ f (g x) where Conn _ g _ = c+{-# INLINE truncate1 #-} -{-# COMPLETE ConnR #-}+truncate2 :: (Num a, Preorder a) => (forall k. Conn k a b) -> (a -> a -> a) -> b -> b -> b+truncate2 c f x y = truncate c $ f (g x) (g y) where Conn _ g _ = c+{-# INLINE truncate2 #-} +---------------------------------------------------------------------+-- Down+---------------------------------------------------------------------++-- | Convert an inverted 'ConnL' to a 'ConnL'.+--+-- > 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 inverted 'ConnR' to a 'ConnR'. -- -- > upR . downR = downR . upR = id@@ -411,122 +501,63 @@     g' x = let (Down y) = g (Down x) in y {-# INLINE upR #-} +-- | Convert a 'ConnL' to an inverted 'ConnL'.+--+-- >>> let counit = upper1 (downL $ conn @_ @() @Ordering) id+-- >>> counit (Down LT)+-- Down LT+-- >>> counit (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 #-}+ -- | Convert a 'ConnR' to an inverted 'ConnR'. ----- >>> lower (downR $ conn @_ @() @Ordering) (Down LT)+-- >>> let unit = lower1 (downR $ conn @_ @() @Ordering) id+-- >>> unit (Down LT) -- Down GT--- >>> lower (downR $ conn @_ @() @Ordering) (Down GT)+-- >>> unit (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'.+-- | Obtain the principal filter in /B/ generated by an element of /A/. ----- > 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 'ConnK' or 'ConnR'.+-- 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 @meet c x y@ is also in /b/. ----- This is the unit of the resulting monad:+-- /filterL/ and /filterR/ commute with /Down/: ----- > x <~ unit c x--- > unit c = floorWith1 c id = floorWith c . embed c+-- > filterL c a b <=> ideal c (Down a) (Down b) ----- >>> unit (conn @_ @() @Ordering) LT--- GT--- >>> unit (conn @_ @() @Ordering) GT--- GT-unit :: ConnR a b -> b -> b-unit c = floorWith1 c id-{-# INLINE unit #-}---- | Reverse round trip through a 'ConnK' or 'ConnR'.+-- > filterL c (Down a) (Down b) <=> ideal c a b ----- > x >~ lower c x+-- /filterL c a/ is upward-closed for all /a/: ----- >>> compare pi $ lower f64f32 pi--- GT-lower :: ConnR a b -> a -> a-lower c = lower1 c id-{-# INLINE lower #-}---- | 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 #-}+-- > a <= b1 && b1 <= b2 => a <= b2+-- > a1 <= b && a2 <= b => meet c (ceiling c a1) (ceiling c a2) <= b+--+-- See <https://en.wikipedia.org/wiki/Filter_(mathematics)>+filterL :: Preorder b => ConnL a b -> a -> b -> Bool+filterL c a b = ceiling c a <~ b+{-# INLINE filterL #-}  -- | 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 `join` y/ is also in /B/.+-- /x/, /y/ in /B/, the element /join c x y/ is also in /B/. ----- /idealWith c a/ is downward-closed for all /a/:+-- /filterR c a/ is downward-closed for all /a/: -- -- > a >= b1 && b1 >= b2 => a >= b2 ----- > a1 >= b && a2 >= b => floor a1 `join` floor a2 >= b+-- > a1 >= b && a2 >= b => join c (floor c a1) (floor c a2) >= b -- -- 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 #-}---- | Extract the right half of a 'ConnK' or 'ConnR'------ This is the adjoint functor theorem for preorders.------ >>> 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 '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 '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 #-}-------------------------------------------------------------------------- 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')-{-# 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'-{-# INLINE strong #-}+filterR :: Preorder b => ConnR a b -> a -> b -> Bool+filterR c a b = b <~ floor c a+{-# INLINE filterR #-}
+ src/Data/Connection/Fixed.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}++module Data.Connection.Fixed (+    Fixed (..),+    showFixed,+    shiftf,++    -- * Uni+    Uni,++    -- * Deci+    Deci,+    f01f00,++    -- * Centi+    Centi,+    f02f00,+    f02f01,++    -- * Milli+    Milli,+    f03f00,+    f03f01,+    f03f02,++    -- * Micro+    Micro,+    f06f00,+    f06f01,+    f06f02,+    f06f03,++    -- * Nano+    Nano,+    f09f00,+    f09f01,+    f09f02,+    f09f03,+    f09f06,++    -- * Pico+    Pico,+    f12f00,+    f12f01,+    f12f02,+    f12f03,+    f12f06,+    f12f09,++    -- * HasResolution+    HasResolution (..),+) where++import safe Data.Connection.Conn+import safe Data.Fixed+import safe Data.Order.Syntax+import safe Prelude hiding (Eq (..), Ord (..))++-- | Shift by n 'units of least precision' where the ULP is determined by the precision.+--+-- This is an analog of 'Data.Connection.Float.shift32' for fixed point numbers.+shiftf :: Integer -> Fixed a -> Fixed a+shiftf j (MkFixed i) = MkFixed (i + j)++-- Deci++f01f00 :: Conn k Deci Uni+f01f00 = triple 10++-- Centi++f02f00 :: Conn k Centi Uni+f02f00 = triple 100++f02f01 :: Conn k Centi Deci+f02f01 = triple 10++-- Milli++f03f00 :: Conn k Milli Uni+f03f00 = triple 1000++f03f01 :: Conn k Milli Deci+f03f01 = triple 100++f03f02 :: Conn k Milli Centi+f03f02 = triple 10++-- Micro++f06f00 :: Conn k Micro Uni+f06f00 = triple $ 10 ^ (6 :: Integer)++f06f01 :: Conn k Micro Deci+f06f01 = triple $ 10 ^ (5 :: Integer)++f06f02 :: Conn k Micro Centi+f06f02 = triple $ 10 ^ (4 :: Integer)++f06f03 :: Conn k Micro Milli+f06f03 = triple $ 10 ^ (3 :: Integer)++-- Nano++f09f00 :: Conn k Nano Uni+f09f00 = triple $ 10 ^ (9 :: Integer)++f09f01 :: Conn k Nano Deci+f09f01 = triple $ 10 ^ (8 :: Integer)++f09f02 :: Conn k Nano Centi+f09f02 = triple $ 10 ^ (7 :: Integer)++f09f03 :: Conn k Nano Milli+f09f03 = triple $ 10 ^ (6 :: Integer)++f09f06 :: Conn k Nano Micro+f09f06 = triple $ 10 ^ (3 :: Integer)++-- Pico++f12f00 :: Conn k Pico Uni+f12f00 = triple $ 10 ^ (12 :: Integer)++f12f01 :: Conn k Pico Deci+f12f01 = triple $ 10 ^ (11 :: Integer)++f12f02 :: Conn k Pico Centi+f12f02 = triple $ 10 ^ (10 :: Integer)++f12f03 :: Conn k Pico Milli+f12f03 = triple $ 10 ^ (9 :: Integer)++f12f06 :: Conn k Pico Micro+f12f06 = triple $ 10 ^ (6 :: Integer)++f12f09 :: Conn k Pico Nano+f12f09 = triple $ 10 ^ (3 :: Integer)++-- Internal++-------------------------++triple :: Integer -> Conn k (Fixed e1) (Fixed e2)+triple prec = Conn f g h+  where+    f (MkFixed i) = MkFixed $ let j = i `div` prec in if i `mod` prec == 0 then j else j + 1+    g (MkFixed i) = MkFixed $ i * prec+    h (MkFixed i) = MkFixed $ let j = i `div` prec in if i `mod` prec == 0 then j else j -1
src/Data/Connection/Float.hs view
@@ -1,34 +1,45 @@ {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ViewPatterns #-}  module Data.Connection.Float (-    -- * Connections-    f32i08,-    f32i16,-    f64i08,-    f64i16,-    f64i32,-    f64f32,-     -- * Float     min32,     max32,+    eps32,     ulp32,     near32,     shift32,+    f32i08,+    f32i16,+    f32i32,+    f32i64,+    f32ixx,+    f32int,      -- * Double     min64,     max64,+    eps64,     ulp64,     near64,     shift64,+    f64i08,+    f64i16,+    f64i32,+    f64i64,+    f64ixx,+    f64int,+    f64f32,     until, ) where  import safe Data.Bool-import safe Data.Connection.Conn+import safe Data.Connection.Conn hiding (ceiling, floor) import safe Data.Int import safe Data.Order import safe Data.Order.Extended@@ -39,56 +50,6 @@ 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 --------------------------------------------------------------------- @@ -114,6 +75,12 @@     (True, False) -> y     (True, True) -> x +-- | Compute the difference between a float and its next largest neighbor.+--+-- See < https://en.wikipedia.org/wiki/Machine_epsilon >.+eps32 :: Float -> Float+eps32 x = shift32 1 x - x+ -- | Compute the signed distance between two floats in units of least precision. -- -- >>> ulp32 1.0 (shift32 1 1.0)@@ -133,7 +100,7 @@ -- -- Required accuracy is specified in units of least precision. ----- See also <https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/>.+-- See <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 @@ -144,16 +111,45 @@ -- >>> shift32 1 1 - 1 -- 1.1920929e-7 -- >>> shift32 1 $ 0/0--- NaN+-- Infinity -- >>> shift32 (-1) $ 0/0--- NaN+-- -Infinity -- >>> shift32 1 $ 1/0 -- Infinity shift32 :: Int32 -> Float -> Float-shift32 n x-    | x ~~ 0 / 0 = x-    | otherwise = int32Float . clamp32 . (+ n) . floatInt32 $ x+shift32 n x =+    if isNaN x == True+        then case signum n of+            -1 -> -1 / 0+            1 -> 1 / 0+            _ -> 0 / 0+        else int32Float . clamp32 . (+ n) . floatInt32 $ x +-- | All 'Data.Int.Int08' values are exactly representable in a 'Float'.+f32i08 :: Conn k Float (Extended Int8)+f32i08 = fxxext++-- | All 'Data.Int.Int16' values are exactly representable in a 'Float'.+--+-- >>> Data.Connection.Conn.ceiling f32i16 32767.0+-- Extended 32767+-- >>> Data.Connection.Conn.ceiling f32i16 32767.1+-- Top+f32i16 :: Conn k Float (Extended Int16)+f32i16 = fxxext++f32i32 :: Conn 'L Float (Extended Int32)+f32i32 = f32ext++f32i64 :: Conn 'L Float (Extended Int64)+f32i64 = f32ext++f32ixx :: Conn 'L Float (Extended Int)+f32ixx = f32ext++f32int :: Conn 'L Float (Extended Integer)+f32int = f32ext+ --------------------------------------------------------------------- -- Double ---------------------------------------------------------------------@@ -180,6 +176,12 @@     (True, False) -> y     (True, True) -> x +-- | Compute the difference between a double and its next largest neighbor.+--+-- See < https://en.wikipedia.org/wiki/Machine_epsilon >.+eps64 :: Double -> Double+eps64 x = shift64 1 x - x+ -- | Compute the signed distance between two doubles in units of least precision. -- -- >>> ulp64 1.0 (shift64 1 1.0)@@ -210,16 +212,63 @@ -- >>> shift64 1 1 - 1 -- 2.220446049250313e-16 -- >>> shift64 1 $ 0/0--- NaN+-- Infinity -- >>> shift64 (-1) $ 0/0--- NaN+-- -Infinity -- >>> shift64 1 $ 1/0 -- Infinity shift64 :: Int64 -> Double -> Double-shift64 n x-    | x ~~ 0 / 0 = x-    | otherwise = int64Double . clamp64 . (+ n) . doubleInt64 $ x+shift64 n x =+    if isNaN x == True+        then case signum n of+            -1 -> -1 / 0+            1 -> 1 / 0+            _ -> 0 / 0+        else int64Double . clamp64 . (+ n) . doubleInt64 $ x +-- | All 'Data.Int.Int08' values are exactly representable in a 'Double'.+f64i08 :: Conn k Double (Extended Int8)+f64i08 = fxxext++-- | All 'Data.Int.Int16' values are exactly representable in a 'Double'.+f64i16 :: Conn k Double (Extended Int16)+f64i16 = fxxext++-- | All 'Data.Int.Int32' values are exactly representable in a 'Double'.+f64i32 :: Conn k Double (Extended Int32)+f64i32 = fxxext++f64i64 :: Conn 'L Double (Extended Int64)+f64i64 = f64ext++f64ixx :: Conn 'L Double (Extended Int)+f64ixx = f64ext++f64int :: Conn 'L Double (Extended Integer)+f64int = f64ext++f64f32 :: Conn k Double Float+f64f32 = Conn f g h+  where+    f x =+        let est = double2Float x+         in if g est >~ x+                then est+                else ascend32 est g x++    g = float2Double++    h x =+        let est = double2Float x+         in if g est <~ x+                then est+                else descend32 est g x++    ascend32 z g1 y = until (\x -> g1 x >~ y) (<~) (shift32 1) z++    descend32 z h1 x = until (\y -> h1 y <~ x) (>~) (shift32 (-1)) z+{-# INLINE f64f32 #-}+ --------------------------------------------------------------------- -- Internal ---------------------------------------------------------------------@@ -245,7 +294,7 @@ signed64 :: Word64 -> Int64 signed64 x     | x < 0x8000000000000000 = fromIntegral x-    | otherwise = fromIntegral (maxBound P.- (x P.- 0x8000000000000000))+    | otherwise = fromIntegral (maxBound - (x - 0x8000000000000000))  -- Non-monotonic function converting from 2s-complement format. unsigned32 :: Int32 -> Word32@@ -256,20 +305,21 @@ -- Non-monotonic function converting from 2s-complement format. unsigned64 :: Int64 -> Word64 unsigned64 x-    | x >~ 0 = fromIntegral x-    | otherwise = 0x8000000000000000 + (maxBound P.- (fromIntegral x))+    | x >= 0 = fromIntegral x+    | otherwise = 0x8000000000000000 + (maxBound - (fromIntegral x))  int32Float :: Int32 -> Float-int32Float = F.castWord32ToFloat . unsigned32+int32Float = castWord32ToFloat . unsigned32 +-- NB: I needed these zeros to avoid some error floatInt32 :: Float -> Int32-floatInt32 = signed32 . (+ 0) . F.castFloatToWord32+floatInt32 = signed32 . (+ 0) . castFloatToWord32  int64Double :: Int64 -> Double-int64Double = F.castWord64ToDouble . unsigned64+int64Double = castWord64ToDouble . unsigned64  doubleInt64 :: Double -> Int64-doubleInt64 = signed64 . (+ 0) . F.castDoubleToWord64+doubleInt64 = signed64 . (+ 0) . castDoubleToWord64  -- Clamp between the int representations of -1/0 and 1/0 clamp32 :: Int32 -> Int32@@ -279,51 +329,59 @@ 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+f32ext :: Integral a => Conn 'L Float (Extended a)+f32ext = ConnL f g   where-    f = liftExtended (~~ -1 / 0) (\x -> x ~~ 0 / 0 || x > high) $ \x -> if x < low then minBound else P.ceiling x+    prec = 24 :: Int -- Float loses integer precision beyond 2^prec+    f x+        | abs x <= 2 ** 24 -1 = Extended (ceiling x)+        | otherwise = case pcompare x 0 of+            Just LT -> Bottom+            _ -> Extended (2 ^ prec) -    g = extended (-1 / 0) (1 / 0) P.fromIntegral+    g Bottom = -2 ** 24+    g Top = 1 / 0+    g (Extended i)+        | abs i P.<= 2 ^ prec -1 = fromIntegral i+        | otherwise = if i P.>= 0 then 1 / 0 else -2 ** 24+{-# INLINE f32ext #-} -    h = liftExtended (\x -> x ~~ 0 / 0 || x < low) (~~ 1 / 0) $ \x -> if x > high then maxBound else P.floor x+f64ext :: Integral a => Conn 'L Double (Extended a)+f64ext = ConnL f g+  where+    prec = 53 :: Int -- Double loses integer precision beyond 2^prec+    f x+        | abs x <= 2 ** 53 -1 = Extended (ceiling x)+        | otherwise = case pcompare x 0 of+            Just LT -> Bottom+            _ -> Extended (2 ^ prec) -    low = -1 - high+    g Bottom = -2 ** 53+    g Top = 1 / 0+    g (Extended i)+        | abs i P.<= 2 ^ prec -1 = fromIntegral i+        | otherwise = if i P.>= 0 then 1 / 0 else -2 ** 53+{-# INLINE f64ext #-} -{---- | Exact embedding up to the largest representable 'Int32'.-f32i32 :: ConnL Float (Maybe Int32)-f32i32 = Conn (nanf f) (nan g) where-  f x | abs x <~ 2**24-1 = P.ceiling x-      | otherwise = if x >~ 0 then 2^24 else minBound+fxxext :: forall a b k. (RealFrac a, Preorder a, Bounded b, Integral b) => Conn k a (Extended b)+fxxext = Conn f g h+  where+    f = liftExtended (~~ -1 / 0) (\x -> x ~~ 0 / 0 || x > high) $ \x -> if x < low then minBound else ceiling x -  g i | abs' i <~ 2^24-1 = fromIntegral i-      | otherwise = if i >~ 0 then 1/0 else -2**24+    g = extended (-1 / 0) (1 / 0) fromIntegral --- | Exact embedding up to the largest representable 'Int32'.-i32f32 :: ConnL (Maybe Int32) Float-i32f32 = Conn (nan g) (nanf f) where-  f x | abs x <~ 2**24-1 = P.floor x-      | otherwise = if x >~ 0 then maxBound else -2^24+    h = liftExtended (\x -> x ~~ 0 / 0 || x < low) (~~ 1 / 0) $ \x -> if x > high then maxBound else floor x -  g i | abs i <~ 2^24-1 = fromIntegral i-      | otherwise = if i >~ 0 then 2**24 else -1/0+    low = fromIntegral $ minBound @b --- | 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+    high = fromIntegral $ maxBound @b+{-# INLINE fxxext #-} -  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'.-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+frac2fixed :: (RealFrac a, HasResolution b) => a -> Fixed b+frac2fixed (flip approxRational 0 -> (n :% d)) = fromInteger n / fromInteger d -  g i | abs' i <~ 2^53-1 = fromIntegral i-      | otherwise = if i >~ 0 then 1/0 else -2**53+--fixed2Float :: forall a . HasResolution a => Fixed a -> Float+--fixed2Float (MkFixed i) = rationalToFloat i $ resolution (Proxy :: Proxy a) -}
src/Data/Connection/Int.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-} {-# LANGUAGE Safe #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-}@@ -54,61 +55,61 @@ import safe Prelude  -- Int16-w08i16 :: ConnL Word8 (Maybe Int16)+w08i16 :: Conn 'L Word8 (Maybe Int16) w08i16 = signed -i08i16 :: ConnL Int8 (Maybe Int16)+i08i16 :: Conn 'L Int8 (Maybe Int16) i08i16 = signed  -- Int32-w08i32 :: ConnL Word8 (Maybe Int32)+w08i32 :: Conn 'L Word8 (Maybe Int32) w08i32 = signed -w16i32 :: ConnL Word16 (Maybe Int32)+w16i32 :: Conn 'L Word16 (Maybe Int32) w16i32 = signed -i08i32 :: ConnL Int8 (Maybe Int32)+i08i32 :: Conn 'L Int8 (Maybe Int32) i08i32 = signed -i16i32 :: ConnL Int16 (Maybe Int32)+i16i32 :: Conn 'L Int16 (Maybe Int32) i16i32 = signed  -- Int64-w08i64 :: ConnL Word8 (Maybe Int64)+w08i64 :: Conn 'L Word8 (Maybe Int64) w08i64 = signed -w16i64 :: ConnL Word16 (Maybe Int64)+w16i64 :: Conn 'L Word16 (Maybe Int64) w16i64 = signed -w32i64 :: ConnL Word32 (Maybe Int64)+w32i64 :: Conn 'L Word32 (Maybe Int64) w32i64 = signed -i08i64 :: ConnL Int8 (Maybe Int64)+i08i64 :: Conn 'L Int8 (Maybe Int64) i08i64 = signed -i16i64 :: ConnL Int16 (Maybe Int64)+i16i64 :: Conn 'L Int16 (Maybe Int64) i16i64 = signed -i32i64 :: ConnL Int32 (Maybe Int64)+i32i64 :: Conn 'L Int32 (Maybe Int64) i32i64 = signed  -- Int-w08ixx :: ConnL Word8 (Maybe Int)+w08ixx :: Conn 'L Word8 (Maybe Int) w08ixx = signed -w16ixx :: ConnL Word16 (Maybe Int)+w16ixx :: Conn 'L Word16 (Maybe Int) w16ixx = signed -w32ixx :: ConnL Word32 (Maybe Int)+w32ixx :: Conn 'L Word32 (Maybe Int) w32ixx = signed -i08ixx :: ConnL Int8 (Maybe Int)+i08ixx :: Conn 'L Int8 (Maybe Int) i08ixx = signed -i16ixx :: ConnL Int16 (Maybe Int)+i16ixx :: Conn 'L Int16 (Maybe Int) i16ixx = signed -i32ixx :: ConnL Int32 (Maybe Int)+i32ixx :: Conn 'L Int32 (Maybe Int) i32ixx = signed  -- | /Caution/: This assumes that 'Int' on your system is 64 bits.@@ -116,37 +117,37 @@ i64ixx = Conn fromIntegral fromIntegral fromIntegral  -- Integer-w08int :: ConnL Word8 (Maybe Integer)+w08int :: Conn 'L Word8 (Maybe Integer) w08int = signed -w16int :: ConnL Word16 (Maybe Integer)+w16int :: Conn 'L Word16 (Maybe Integer) w16int = signed -w32int :: ConnL Word32 (Maybe Integer)+w32int :: Conn 'L Word32 (Maybe Integer) w32int = signed -w64int :: ConnL Word64 (Maybe Integer)+w64int :: Conn 'L Word64 (Maybe Integer) w64int = signed -wxxint :: ConnL Word (Maybe Integer)+wxxint :: Conn 'L Word (Maybe Integer) wxxint = signed -natint :: ConnL Natural (Maybe Integer)+natint :: Conn 'L Natural (Maybe Integer) natint = ConnL (fmap fromIntegral . fromPred (/= 0)) (maybe 0 $ fromInteger . max 0) -i08int :: ConnL Int8 (Maybe Integer)+i08int :: Conn 'L Int8 (Maybe Integer) i08int = signed -i16int :: ConnL Int16 (Maybe Integer)+i16int :: Conn 'L Int16 (Maybe Integer) i16int = signed -i32int :: ConnL Int32 (Maybe Integer)+i32int :: Conn 'L Int32 (Maybe Integer) i32int = signed -i64int :: ConnL Int64 (Maybe Integer)+i64int :: Conn 'L Int64 (Maybe Integer) i64int = signed -ixxint :: ConnL Int (Maybe Integer)+ixxint :: Conn 'L Int (Maybe Integer) ixxint = signed  ---------------------------------------------------------------------@@ -156,7 +157,7 @@ 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 :: forall a b. (Bounded a, Integral a, Integral b) => Conn 'L a (Maybe b) signed = ConnL f g   where     f = fmap fromIntegral . fromPred (/= minBound)
src/Data/Connection/Property.hs view
@@ -8,117 +8,138 @@ -- --  \( \forall x, y : f \dashv g \Rightarrow f (x) \leq b \Leftrightarrow x \leq g (y) \) -----  \( \forall x, y : x \leq y \Rightarrow f (x) \leq f (y) \)------  \( \forall x, y : x \leq y \Rightarrow g (x) \leq g (y) \)--- --  \( \forall x : f \dashv g \Rightarrow x \leq g \circ f (x) \) -- --  \( \forall x : f \dashv g \Rightarrow f \circ g (x) \leq x \)------  \( \forall x : unit \circ unit (x) \sim unit (x) \)------  \( \forall x : counit \circ counit (x) \sim counit (x) \)------  \( \forall x : counit \circ f (x) \sim f (x) \)------  \( \forall x : unit \circ g (x) \sim g (x) \)-module Data.Connection.Property where+module Data.Connection.Property (+    -- * Adjointness+    adjointL,+    adjointR,+    adjoint,+    adjunction, +    -- * Closure+    closedL,+    closedR,+    closed,+    kernelL,+    kernelR,+    kernel,+    invertible,++    -- * Monotonicity+    monotonicR,+    monotonicL,+    monotonic,+    monotone,++    -- * Idempotence+    idempotentL,+    idempotentR,+    idempotent,+    projective,+) where+ import Data.Connection import Data.Order import Data.Order.Property import Prelude hiding (Num (..), Ord (..), ceiling, floor) +-- Adjointness++-------------------------+ -- | \( \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) => 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  adjointR :: (Preorder a, Preorder b) => ConnR a b -> a -> b -> Bool adjointR (ConnR f g) = adjunction (>~) (>~) g f +adjoint :: (Preorder a, Preorder b) => (forall k. Conn k a b) -> a -> b -> Bool+adjoint t a b =+    adjointL t a b+        && adjointR t a b+        && adjointL (connL t) b a+        && adjointR (connR t) b a++-- | \( \forall a: f a \leq b \Leftrightarrow a \leq g b \)+--+-- A monotone Galois connection is defined by @adjunction (<~) (<~)@,+-- while 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++-- Closure++-------------------------+ -- | \( \forall x : f \dashv g \Rightarrow x \leq g \circ f (x) \) -- -- This is a required property.-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 closedL (ConnL f g) = invertible (>~) f g  closedR :: (Preorder a, Preorder b) => ConnR a b -> a -> Bool closedR (ConnR f g) = invertible (<~) g f +closed :: (Preorder a, Preorder b) => (forall k. Conn k a b) -> a -> Bool+closed t a = closedL t a && closedR t a+ -- | \( \forall x : f \dashv g \Rightarrow x \leq g \circ f (x) \) -- -- This is a required property.-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 kernelL (ConnL f g) = invertible (<~) g f  kernelR :: (Preorder a, Preorder b) => ConnR a b -> b -> Bool kernelR (ConnR f g) = invertible (>~) f g +kernel :: (Preorder a, Preorder b) => (forall k. Conn k a b) -> b -> Bool+kernel t b = kernelL t b && kernelR t b++-- | \( \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++-- Monotonicity++-------------------------+ -- | \( \forall x, y : x \leq y \Rightarrow f (x) \leq f (y) \) -- -- This is a required property.-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 monotonicR (ConnR f g) a1 a2 b1 b2 = monotone (<~) (<~) g a1 a2 && monotone (<~) (<~) f b1 b2  monotonicL :: (Preorder a, Preorder b) => ConnL a b -> a -> a -> b -> b -> Bool monotonicL (ConnL f g) a1 a2 b1 b2 = monotone (<~) (<~) f a1 a2 && monotone (<~) (<~) g b1 b2 --- | \( \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) => 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 (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 (unit c) a && projective (~~) f (lower c) b-------------------------------------------------------------------------- Properties of general relations----------------------------------------------------------------------+monotonic :: (Preorder a, Preorder b) => (forall k. Conn k 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  -- | \( \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+-- Idempotence --- | \( \forall a: f a \leq b \Leftrightarrow a \leq g b \)+-------------------------++-- | \( \forall x: f \dashv g \Rightarrow counit \circ f (x) \sim f (x) \wedge unit \circ g (x) \sim g (x) \) ----- 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+-- See <https://ncatlab.org/nlab/show/idempotent+adjunction>+idempotentL :: (Preorder a, Preorder b) => ConnL a b -> a -> b -> Bool+idempotentL c@(ConnL f g) a b = projective (~~) g (upper1 c id) b && projective (~~) f (ceiling1 c id) a --- | \( \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+idempotentR :: (Preorder a, Preorder b) => ConnR a b -> a -> b -> Bool+idempotentR c@(ConnR f g) a b = projective (~~) g (floor1 c id) a && projective (~~) f (lower1 c id) b +idempotent :: (Preorder a, Preorder b) => (forall k. Conn k a b) -> a -> b -> Bool+idempotent t a b = idempotentL t a b && idempotentR t a b+ -- | \( \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
@@ -2,21 +2,23 @@ {-# LANGUAGE Safe #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ViewPatterns #-}  module Data.Connection.Ratio (     Ratio (..),     reduce,-    shiftd,+    shiftr,      -- * Rational-    ratf32,-    ratf64,     rati08,     rati16,     rati32,     rati64,     ratixx,     ratint,+    ratfix,+    ratf32,+    ratf64,      -- * Positive     posw08,@@ -27,18 +29,19 @@     posnat, ) where -import safe Data.Connection.Conn-import safe qualified Data.Connection.Float as Float+import safe Data.Connection.Conn hiding (ceiling, floor)+import safe Data.Connection.Fixed+import safe 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.Proxy import safe Data.Ratio import safe Data.Word import safe GHC.Real (Ratio (..), Rational) import safe Numeric.Natural-import safe Prelude hiding (Ord (..), until)-import safe qualified Prelude as P+import safe Prelude hiding (Eq (..), Ord (..), until)  -- | A total version of 'GHC.Real.reduce'. reduce :: Integral a => Ratio a -> Ratio a@@ -48,74 +51,89 @@ -- | Shift by n 'units of least precision' where the ULP is determined by the denominator -- -- 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+shiftr :: Num a => a -> Ratio a -> Ratio a+shiftr n (x :% y) = (n + x) :% y  --------------------------------------------------------------------- -- Ratio Integer ---------------------------------------------------------------------  rati08 :: Conn k Rational (Extended Int8)-rati08 = signedTriple+rati08 = tripleI  rati16 :: Conn k Rational (Extended Int16)-rati16 = signedTriple+rati16 = tripleI  rati32 :: Conn k Rational (Extended Int32)-rati32 = signedTriple+rati32 = tripleI  rati64 :: Conn k Rational (Extended Int64)-rati64 = signedTriple+rati64 = tripleI  ratixx :: Conn k Rational (Extended Int)-ratixx = signedTriple+ratixx = tripleI  ratint :: Conn k Rational (Extended Integer) ratint = Conn f g h   where-    f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling+    f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) ceiling -    g = extended ninf pinf P.fromIntegral+    g = extended ninf pinf fromIntegral -    h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor+    h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) floor +ratfix :: forall e k. HasResolution e => Conn k Rational (Extended (Fixed e))+ratfix = Conn f' g h'+  where+    prec = resolution (Proxy :: Proxy e)++    f (reduce . (* (toRational prec)) -> n :% d) = MkFixed $ let i = n `div` d in if n `mod` d == 0 then i else i + 1++    f' = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) f++    g = extended ninf pinf toRational++    h (reduce . (* (toRational prec)) -> n :% d) = MkFixed $ n `div` d++    h' = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) h+ ratf32 :: Conn k Rational Float-ratf32 = Conn (toFloating f) (fromFloating g) (toFloating h)+ratf32 = Conn (toFractional f) (fromFractional g) (toFractional h)   where     f x =-        let est = P.fromRational x-         in if fromFloating g est >~ x+        let est = fromRational x+         in if fromFractional g est >~ x                 then est-                else ascendf est (fromFloating g) x+                else ascendf est (fromFractional g) x      g = flip approxRational 0      h x =-        let est = P.fromRational x-         in if fromFloating g est <~ x+        let est = fromRational x+         in if fromFractional g est <~ x                 then est-                else descendf est (fromFloating g) x+                else descendf est (fromFractional g) x      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)+ratf64 = Conn (toFractional f) (fromFractional g) (toFractional h)   where     f x =-        let est = P.fromRational x-         in if fromFloating g est >~ x+        let est = fromRational x+         in if fromFractional g est >~ x                 then est-                else ascendf est (fromFloating g) x+                else ascendf est (fromFractional g) x      g = flip approxRational 0      h x =-        let est = P.fromRational x-         in if fromFloating g est <~ x+        let est = fromRational x+         in if fromFractional g est <~ x                 then est-                else descendf est (fromFloating g) x+                else descendf est (fromFractional g) x      ascendf z g1 y = Float.until (\x -> g1 x >~ y) (<~) (Float.shift64 1) z @@ -126,28 +144,28 @@ ---------------------------------------------------------------------  posw08 :: Conn k Positive (Lowered Word8)-posw08 = unsignedTriple+posw08 = tripleW  posw16 :: Conn k Positive (Lowered Word16)-posw16 = unsignedTriple+posw16 = tripleW  posw32 :: Conn k Positive (Lowered Word32)-posw32 = unsignedTriple+posw32 = tripleW  posw64 :: Conn k Positive (Lowered Word64)-posw64 = unsignedTriple+posw64 = tripleW  poswxx :: Conn k Positive (Lowered Word)-poswxx = unsignedTriple+poswxx = tripleW  posnat :: Conn k Positive (Lowered Natural) posnat = Conn f g h   where-    f = liftEitherR (\x -> x ~~ nan || x ~~ pinf) P.ceiling+    f = liftEitherR (\x -> x ~~ nan || x ~~ pinf) ceiling -    g = either P.fromIntegral (const pinf)+    g = either 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 floor x  --------------------------------------------------------------------- -- Internal@@ -162,45 +180,45 @@ nan :: Num a => Ratio a nan = 0 :% 0 -unsignedTriple :: forall a k. (Bounded a, Integral a) => Conn k Positive (Lowered a)-unsignedTriple = Conn f g h+tripleW :: forall a k. (Bounded a, Integral a) => Conn k Positive (Lowered a)+tripleW = Conn f g h   where     f x         | x ~~ nan = Right maxBound         | x > high = Right maxBound-        | otherwise = Left $ P.ceiling x+        | otherwise = Left $ ceiling x -    g = either P.fromIntegral (const pinf)+    g = either fromIntegral (const pinf)      h x         | x ~~ nan = Left minBound         | x ~~ pinf = Right maxBound         | x > high = Left maxBound-        | otherwise = Left $ P.floor x+        | otherwise = Left $ floor x -    high = P.fromIntegral @a maxBound+    high = fromIntegral @a maxBound -signedTriple :: forall a k. (Bounded a, Integral a) => Conn k Rational (Extended a)-signedTriple = Conn f g h+tripleI :: forall a k. (Bounded a, Integral a) => Conn k Rational (Extended a)+tripleI = Conn f g h   where-    f = liftExtended (~~ ninf) (\x -> x ~~ nan || x > high) $ \x -> if x < low then minBound else P.ceiling x+    f = liftExtended (~~ ninf) (\x -> x ~~ nan || x > high) $ \x -> if x < low then minBound else ceiling x -    g = extended ninf pinf P.fromIntegral+    g = extended ninf pinf fromIntegral -    h = liftExtended (\x -> x ~~ nan || x < low) (~~ pinf) $ \x -> if x > high then maxBound else P.floor x+    h = liftExtended (\x -> x ~~ nan || x < low) (~~ pinf) $ \x -> if x > high then maxBound else floor x -    high = P.fromIntegral @a maxBound+    high = fromIntegral @a maxBound     low = -1 - high -toFloating :: Fractional a => (Rational -> a) -> Rational -> a-toFloating f x+toFractional :: Fractional a => (Rational -> a) -> Rational -> a+toFractional f x     | x ~~ nan = 0 / 0     | x ~~ ninf = (-1) / 0     | x ~~ pinf = 1 / 0     | otherwise = f x -fromFloating :: (Order a, Fractional a) => (a -> Rational) -> a -> Rational-fromFloating f x+fromFractional :: (Order a, Fractional a) => (a -> Rational) -> a -> Rational+fromFractional f x     | x ~~ 0 / 0 = nan     | x ~~ (-1) / 0 = ninf     | x ~~ 1 / 0 = pinf@@ -221,9 +239,9 @@ ratpos :: Conn k Rational Positive ratpos = Conn k f g h where -  f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling+  f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) ceiling -  g = extended minBound maxBound P.fromIntegral+  g = extended minBound maxBound fromIntegral -  h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor+  h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) floor -}
src/Data/Lattice.hs view
@@ -60,7 +60,7 @@  import safe Data.Bifunctor (bimap) import safe Data.Bool hiding (not)-import safe Data.Connection.Class+import safe Data.Connection.Class hiding ((/\), (\/)) import safe Data.Connection.Conn import safe Data.Either import safe Data.Int@@ -72,7 +72,7 @@ import safe Data.Order.Syntax import safe qualified Data.Set as Set import safe Data.Word-import safe Prelude hiding (Eq (..), Ord (..), not)+import safe Prelude hiding (Eq (..), Ord (..), ceiling, floor, not) import safe qualified Prelude as P  -------------------------------------------------------------------------------@@ -161,31 +161,31 @@  -- | Lattice meet. ----- > (/\) = curry $ floorWith semilattice+-- > (/\) = curry $ floor semilattice (/\) :: Meet a => a -> a -> a-(/\) = curry $ floorWith semilattice+(/\) = curry $ floor semilattice  -- | The unique top element of a bounded lattice -- -- > x /\ top = x -- > x \/ top = top top :: Meet a => a-top = floorWith bounded ()+top = floor bounded ()  infixr 5 \/  -- | Lattice join. ----- > (\/) = curry $ ceilingWith semilattice+-- > (\/) = curry $ lower semilattice (\/) :: Join a => a -> a -> a-(\/) = curry $ ceilingWith semilattice+(\/) = curry $ ceiling semilattice  -- | The unique bottom element of a bounded lattice -- -- > x /\ bottom = bottom -- > x \/ bottom = x bottom :: Join a => a-bottom = ceilingWith bounded ()+bottom = ceiling bounded ()  ------------------------------------------------------------------------------- -- Heyting algebras@@ -278,7 +278,7 @@ -- >>> True // True -- True (//) :: Algebra 'R a => a -> a -> a-(//) = floorWith . algebra+(//) = floor . algebra  -- | Intuitionistic equivalence. --@@ -363,7 +363,7 @@ -- >>> [GT,EQ] \\ [LT] -- fromList [EQ,GT] (\\) :: Algebra 'L a => a -> a -> a-(\\) = flip $ ceilingWith . algebra+(\\) = flip $ ceiling . algebra  -- | Intuitionistic co-equivalence. equiv :: Algebra 'L a => a -> a -> a@@ -513,7 +513,6 @@     not LT = GT     not EQ = EQ     not GT = LT-instance Boolean Ordering  instance Semilattice k Word8 instance Algebra 'L Word8 where algebra = coheyting impliesL@@ -678,7 +677,7 @@      semilattice = ConnL f fork       where-        f = uncurry $ Map.unionWith (curry $ ceilingWith semilattice)+        f = uncurry $ Map.unionWith (curry $ ceiling semilattice)  instance (Total k, Join a) => Algebra 'L (Map.Map k a) where     algebra = coheyting (Map.\\)@@ -688,7 +687,7 @@      semilattice = ConnL f fork       where-        f = uncurry $ IntMap.unionWith (curry $ ceilingWith semilattice)+        f = uncurry $ IntMap.unionWith (curry $ ceiling semilattice)  instance (Join a) => Algebra 'L (IntMap.IntMap a) where     algebra = coheyting (IntMap.\\)
src/Data/Order.hs view
@@ -36,6 +36,7 @@ import safe Data.Complex import safe Data.Either import safe qualified Data.Eq as Eq+import safe Data.Fixed import safe Data.Functor.Identity import safe Data.Int import safe qualified Data.IntMap as IntMap@@ -287,7 +288,20 @@ deriving via (Base Int64) instance Preorder Int64 deriving via (Base Integer) instance Preorder Integer ---TODO move to Order and derive Preorder as well+deriving via (Base (Fixed e)) instance Preorder (Fixed e)++-- | An < https://en.wikipedia.org/wiki/Modular_lattice#Examples /N5/ > lattice.+--+--  A non-modular lattice formed by the < https://en.wikipedia.org/wiki/Extended_real_number_line affine extended >+--  reals along with a /NaN/ value that is incomparable to any finite number, i.e.:+--+--  > pcompare (N5 NaN) (N5 x) = pcompare (N5 x) (N5 NaN) = Nothing+--+--  for any finite /x/.+--+--  > N5 NaN == N5 NaN = True+--  > N5 NaN < N5 (1/0) = True+--  > N5 NaN > N5 (-1/0) = True newtype N5 a = N5 {getN5 :: a}     deriving stock (Eq, Show, Functor)     deriving (Applicative) via Identity
test/Test/Data/Connection.hs view
@@ -11,6 +11,7 @@ import Data.Lattice import Data.Int import Data.Word+import Data.Fixed import Data.Order import Data.Order.Extended import Data.Order.Interval@@ -53,9 +54,11 @@ f64 = gen_flt $ G.double rd  rat :: Gen (Ratio Integer)-rat = G.frequency [(49, gen), (1, G.element [-1 :% 0, 1 :% 0, 0 :% 0])]-  where gen = G.realFrac_ (R.linearFracFrom 0 (- 2^127) (2^127))+rat = G.realFrac_ $ R.linearFracFrom 0 (- 2^(127 :: Integer)) (2^(127 :: Integer)) +rat' :: Gen (Ratio Integer)+rat' = G.frequency [(49, rat), (1, G.element [-1 :% 0, 1 :% 0, 0 :% 0])]+ pos :: Gen (Ratio Natural) pos = G.frequency [(49, gen), (1, G.element [1 :% 0, 0 :% 0])]   where gen = G.realFrac_ (R.linearFracFrom 0 0 (2^127))@@ -85,8 +88,8 @@   x' <- forAll f32   o <- forAll ord   o' <- forAll ord-  r <- forAll rat-  r' <- forAll rat+  r <- forAll rat'+  r' <- forAll rat'    assert $ Prop.adjoint (conn @_ @() @Ordering) () o   assert $ Prop.closed (conn @_ @() @Ordering) ()
+ test/Test/Data/Connection/Fixed.hs view
@@ -0,0 +1,153 @@+{-# LANGUAGE TemplateHaskell #-}++module Test.Data.Connection.Fixed where++import Data.Connection.Fixed+import qualified Data.Connection.Property as Prop+import Hedgehog+import qualified Hedgehog.Gen as G+import Test.Data.Connection++fxx :: Gen (Fixed k)+fxx = MkFixed <$> G.integral ri'++prop_connections_micro :: Property+prop_connections_micro = withTests 1000 . property $ do+    f00 <- forAll fxx+    f01 <- forAll fxx+    f02 <- forAll fxx+    f03 <- forAll fxx+    f06 <- forAll fxx++    f00' <- forAll fxx+    f01' <- forAll fxx+    f02' <- forAll fxx+    f03' <- forAll fxx+    f06' <- forAll fxx++    assert $ Prop.adjoint f06f00 f06 f00+    assert $ Prop.closed f06f00 f06+    assert $ Prop.kernel f06f00 f00+    assert $ Prop.monotonic f06f00 f06 f06' f00 f00'+    assert $ Prop.idempotent f06f00 f06 f00++    assert $ Prop.adjoint f06f01 f06 f01+    assert $ Prop.closed f06f01 f06+    assert $ Prop.kernel f06f01 f01+    assert $ Prop.monotonic f06f01 f06 f06' f01 f01'+    assert $ Prop.idempotent f06f01 f06 f01++    assert $ Prop.adjoint f06f02 f06 f02+    assert $ Prop.closed f06f02 f06+    assert $ Prop.kernel f06f02 f02+    assert $ Prop.monotonic f06f02 f06 f06' f02 f02'+    assert $ Prop.idempotent f06f02 f06 f02++    assert $ Prop.adjoint f06f03 f06 f03+    assert $ Prop.closed f06f03 f06+    assert $ Prop.kernel f06f03 f03+    assert $ Prop.monotonic f06f03 f06 f06' f03 f03'+    assert $ Prop.idempotent f06f03 f06 f03++prop_connections_nano :: Property+prop_connections_nano = withTests 1000 . property $ do+    f00 <- forAll fxx+    f01 <- forAll fxx+    f02 <- forAll fxx+    f03 <- forAll fxx+    f06 <- forAll fxx+    f09 <- forAll fxx++    f00' <- forAll fxx+    f01' <- forAll fxx+    f02' <- forAll fxx+    f03' <- forAll fxx+    f06' <- forAll fxx+    f09' <- forAll fxx++    assert $ Prop.adjoint f09f00 f09 f00+    assert $ Prop.closed f09f00 f09+    assert $ Prop.kernel f09f00 f00+    assert $ Prop.monotonic f09f00 f09 f09' f00 f00'+    assert $ Prop.idempotent f09f00 f09 f00++    assert $ Prop.adjoint f09f01 f09 f01+    assert $ Prop.closed f09f01 f09+    assert $ Prop.kernel f09f01 f01+    assert $ Prop.monotonic f09f01 f09 f09' f01 f01'+    assert $ Prop.idempotent f09f01 f09 f01++    assert $ Prop.adjoint f09f02 f09 f02+    assert $ Prop.closed f09f02 f09+    assert $ Prop.kernel f09f02 f02+    assert $ Prop.monotonic f09f02 f09 f09' f02 f02'+    assert $ Prop.idempotent f09f02 f09 f02++    assert $ Prop.adjoint f09f03 f09 f03+    assert $ Prop.closed f09f03 f09+    assert $ Prop.kernel f09f03 f03+    assert $ Prop.monotonic f09f03 f09 f09' f03 f03'+    assert $ Prop.idempotent f09f03 f09 f03++    assert $ Prop.adjoint f09f06 f09 f06+    assert $ Prop.closed f09f06 f09+    assert $ Prop.kernel f09f06 f06+    assert $ Prop.monotonic f09f06 f09 f09' f06 f06'+    assert $ Prop.idempotent f09f06 f09 f06++prop_connections_pico :: Property+prop_connections_pico = withTests 1000 . property $ do+    f00 <- forAll fxx+    f01 <- forAll fxx+    f02 <- forAll fxx+    f03 <- forAll fxx+    f06 <- forAll fxx+    f09 <- forAll fxx+    f12 <- forAll fxx++    f00' <- forAll fxx+    f01' <- forAll fxx+    f02' <- forAll fxx+    f03' <- forAll fxx+    f06' <- forAll fxx+    f09' <- forAll fxx+    f12' <- forAll fxx++    assert $ Prop.adjoint f12f00 f12 f00+    assert $ Prop.closed f12f00 f12+    assert $ Prop.kernel f12f00 f00+    assert $ Prop.monotonic f12f00 f12 f12' f00 f00'+    assert $ Prop.idempotent f12f00 f12 f00++    assert $ Prop.adjoint f12f01 f12 f01+    assert $ Prop.closed f12f01 f12+    assert $ Prop.kernel f12f01 f01+    assert $ Prop.monotonic f12f01 f12 f12' f01 f01'+    assert $ Prop.idempotent f12f01 f12 f01++    assert $ Prop.adjoint f12f02 f12 f02+    assert $ Prop.closed f12f02 f12+    assert $ Prop.kernel f12f02 f02+    assert $ Prop.monotonic f12f02 f12 f12' f02 f02'+    assert $ Prop.idempotent f12f02 f12 f02++    assert $ Prop.adjoint f12f03 f12 f03+    assert $ Prop.closed f12f03 f12+    assert $ Prop.kernel f12f03 f03+    assert $ Prop.monotonic f12f03 f12 f12' f03 f03'+    assert $ Prop.idempotent f12f03 f12 f03++    assert $ Prop.adjoint f12f06 f12 f06+    assert $ Prop.closed f12f06 f12+    assert $ Prop.kernel f12f06 f06+    assert $ Prop.monotonic f12f06 f12 f12' f06 f06'+    assert $ Prop.idempotent f12f06 f12 f06++    assert $ Prop.adjoint f12f09 f12 f09+    assert $ Prop.closed f12f09 f12+    assert $ Prop.kernel f12f09 f09+    assert $ Prop.monotonic f12f09 f12 f12' f09 f09'+    assert $ Prop.idempotent f12f09 f12 f09++tests :: IO Bool+tests = checkParallel $$(discover)
test/Test/Data/Connection/Float.hs view
@@ -1,93 +1,188 @@ {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ViewPatterns #-}+ module Test.Data.Connection.Float where  import Data.Connection.Conn import Data.Connection.Float+import Data.Fixed import Data.Int-import Hedgehog-import Prelude hiding (Ord(..),Bounded, until)-import Test.Data.Connection+import Data.Order+ import qualified Data.Connection.Property as Prop+import Hedgehog import qualified Hedgehog.Gen as G-+import Test.Data.Connection  prop_connection_f32i08 :: Property prop_connection_f32i08 = withTests 1000 . property $ do-  x <- forAll f32-  x' <- forAll f32-  y <- forAll $ gen_extended $ G.integral (ri @Int8)-  y' <- forAll $ gen_extended $ G.integral (ri @Int8)+    x <- forAll f32+    x' <- forAll f32+    y <- forAll $ gen_extended $ G.integral (ri @Int8)+    y' <- forAll $ gen_extended $ G.integral (ri @Int8) -  assert $ Prop.adjoint (f32i08) x y-  assert $ Prop.closed (f32i08) x-  assert $ Prop.kernel (f32i08) y-  assert $ Prop.monotonic (f32i08) x x' y y'-  assert $ Prop.idempotent (f32i08) x y+    assert $ Prop.adjoint f32i08 x y+    assert $ Prop.closed f32i08 x+    assert $ Prop.kernel f32i08 y+    assert $ Prop.monotonic f32i08 x x' y y'+    assert $ Prop.idempotent f32i08 x y  prop_connection_f32i16 :: Property prop_connection_f32i16 = withTests 1000 . property $ do-  x <- forAll f32-  x' <- forAll f32-  y <- forAll $ gen_extended $ G.integral (ri @Int16)-  y' <- forAll $ gen_extended $ G.integral (ri @Int16)+    x <- forAll f32+    x' <- forAll f32+    y <- forAll $ gen_extended $ G.integral (ri @Int16)+    y' <- forAll $ gen_extended $ G.integral (ri @Int16) -  assert $ Prop.adjoint (f32i16) x y-  assert $ Prop.closed (f32i16) x-  assert $ Prop.kernel (f32i16) y-  assert $ Prop.monotonic (f32i16) x x' y y'-  assert $ Prop.idempotent (f32i16) x y+    assert $ Prop.adjoint f32i16 x y+    assert $ Prop.closed f32i16 x+    assert $ Prop.kernel f32i16 y+    assert $ Prop.monotonic f32i16 x x' y y'+    assert $ Prop.idempotent f32i16 x y +prop_connection_f32i32 :: Property+prop_connection_f32i32 = withTests 1000 . property $ do+    x <- forAll f32+    x' <- forAll f32+    y <- forAll $ gen_extended $ G.integral (ri @Int32)+    y' <- forAll $ gen_extended $ G.integral (ri @Int32)++    assert $ Prop.adjointL f32i32 x y+    assert $ Prop.closedL f32i32 x+    assert $ Prop.kernelL f32i32 y+    assert $ Prop.monotonicL f32i32 x x' y y'+    assert $ Prop.idempotentL f32i32 x y++prop_connection_f32i64 :: Property+prop_connection_f32i64 = withTests 1000 . property $ do+    x <- forAll f32+    x' <- forAll f32+    y <- forAll $ gen_extended $ G.integral (ri @Int64)+    y' <- forAll $ gen_extended $ G.integral (ri @Int64)++    assert $ Prop.adjointL f32i64 x y+    assert $ Prop.closedL f32i64 x+    assert $ Prop.kernelL f32i64 y+    assert $ Prop.monotonicL f32i64 x x' y y'+    assert $ Prop.idempotentL f32i64 x y++prop_connection_f32ixx :: Property+prop_connection_f32ixx = withTests 1000 . property $ do+    x <- forAll f32+    x' <- forAll f32+    y <- forAll $ gen_extended $ G.integral (ri @Int)+    y' <- forAll $ gen_extended $ G.integral (ri @Int)++    assert $ Prop.adjointL f32ixx x y+    assert $ Prop.closedL f32ixx x+    assert $ Prop.kernelL f32ixx y+    assert $ Prop.monotonicL f32ixx x x' y y'+    assert $ Prop.idempotentL f32ixx x y++prop_connection_f32int :: Property+prop_connection_f32int = withTests 1000 . property $ do+    x <- forAll f32+    x' <- forAll f32+    y <- forAll $ gen_extended $ G.integral ri'+    y' <- forAll $ gen_extended $ G.integral ri'++    assert $ Prop.adjointL f32int x y+    assert $ Prop.closedL f32int x+    assert $ Prop.kernelL f32int y+    assert $ Prop.monotonicL f32int x x' y y'+    assert $ Prop.idempotentL f32int x y+ prop_connection_f64i08 :: Property prop_connection_f64i08 = withTests 1000 . property $ do-  x <- forAll f64-  x' <- forAll f64-  y <- forAll $ gen_extended $ G.integral (ri @Int8)-  y' <- forAll $ gen_extended $ G.integral (ri @Int8)+    x <- forAll f64+    x' <- forAll f64+    y <- forAll $ gen_extended $ G.integral (ri @Int8)+    y' <- forAll $ gen_extended $ G.integral (ri @Int8) -  assert $ Prop.adjoint (f64i08) x y-  assert $ Prop.closed (f64i08) x-  assert $ Prop.kernel (f64i08) y-  assert $ Prop.monotonic (f64i08) x x' y y'-  assert $ Prop.idempotent (f64i08) x y+    assert $ Prop.adjoint f64i08 x y+    assert $ Prop.closed f64i08 x+    assert $ Prop.kernel f64i08 y+    assert $ Prop.monotonic f64i08 x x' y y'+    assert $ Prop.idempotent f64i08 x y  prop_connection_f64i16 :: Property prop_connection_f64i16 = withTests 1000 . property $ do-  x <- forAll f64-  x' <- forAll f64-  y <- forAll $ gen_extended $ G.integral (ri @Int16)-  y' <- forAll $ gen_extended $ G.integral (ri @Int16)+    x <- forAll f64+    x' <- forAll f64+    y <- forAll $ gen_extended $ G.integral (ri @Int16)+    y' <- forAll $ gen_extended $ G.integral (ri @Int16) -  assert $ Prop.adjoint (f64i16) x y-  assert $ Prop.closed (f64i16) x-  assert $ Prop.kernel (f64i16) y-  assert $ Prop.monotonic (f64i16) x x' y y'-  assert $ Prop.idempotent (f64i16) x y+    assert $ Prop.adjoint f64i16 x y+    assert $ Prop.closed f64i16 x+    assert $ Prop.kernel f64i16 y+    assert $ Prop.monotonic f64i16 x x' y y'+    assert $ Prop.idempotent f64i16 x y  prop_connection_f64i32 :: Property prop_connection_f64i32 = withTests 1000 . property $ do-  x <- forAll f64-  x' <- forAll f64-  y <- forAll $ gen_extended $ G.integral (ri @Int32)-  y' <- forAll $ gen_extended $ G.integral (ri @Int32)+    x <- forAll f64+    x' <- forAll f64+    y <- forAll $ gen_extended $ G.integral (ri @Int32)+    y' <- forAll $ gen_extended $ G.integral (ri @Int32) -  assert $ Prop.adjoint (f64i32) x y-  assert $ Prop.closed (f64i32) x-  assert $ Prop.kernel (f64i32) y-  assert $ Prop.monotonic (f64i32) x x' y y'-  assert $ Prop.idempotent (f64i32) x y+    assert $ Prop.adjoint f64i32 x y+    assert $ Prop.closed f64i32 x+    assert $ Prop.kernel f64i32 y+    assert $ Prop.monotonic f64i32 x x' y y'+    assert $ Prop.idempotent f64i32 x y +prop_connection_f64i64 :: Property+prop_connection_f64i64 = withTests 1000 . property $ do+    x <- forAll f64+    x' <- forAll f64+    y <- forAll $ gen_extended $ G.integral (ri @Int64)+    y' <- forAll $ gen_extended $ G.integral (ri @Int64)++    assert $ Prop.adjointL f64i64 x y+    assert $ Prop.closedL f64i64 x+    assert $ Prop.kernelL f64i64 y+    assert $ Prop.monotonicL f64i64 x x' y y'+    assert $ Prop.idempotentL f64i64 x y++prop_connection_f64ixx :: Property+prop_connection_f64ixx = withTests 1000 . property $ do+    x <- forAll f64+    x' <- forAll f64+    y <- forAll $ gen_extended $ G.integral (ri @Int)+    y' <- forAll $ gen_extended $ G.integral (ri @Int)++    assert $ Prop.adjointL f64ixx x y+    assert $ Prop.closedL f64ixx x+    assert $ Prop.kernelL f64ixx y+    assert $ Prop.monotonicL f64ixx x x' y y'+    assert $ Prop.idempotentL f64ixx x y++prop_connection_f64int :: Property+prop_connection_f64int = withTests 1000 . property $ do+    x <- forAll f64+    x' <- forAll f64+    y <- forAll $ gen_extended $ G.integral ri'+    y' <- forAll $ gen_extended $ G.integral ri'++    assert $ Prop.adjointL f64int x y+    assert $ Prop.closedL f64int x+    assert $ Prop.kernelL f64int y+    assert $ Prop.monotonicL f64int x x' y y'+    assert $ Prop.idempotentL f64int x y+ prop_connection_f64f32 :: Property prop_connection_f64f32 = withTests 1000 . property $ do-  x <- forAll f64-  x' <- forAll f64-  y <- forAll f32-  y' <- forAll f32+    x <- forAll f64+    x' <- forAll f64+    y <- forAll f32+    y' <- forAll f32 -  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+    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/Ratio.hs view
@@ -1,170 +1,218 @@ {-# LANGUAGE TemplateHaskell #-}-{-# Language AllowAmbiguousTypes #-}+{-# LANGUAGE TypeApplications #-}+ module Test.Data.Connection.Ratio where +import qualified Data.Connection.Property as Prop+import Data.Connection.Ratio+import Data.Fixed import Data.Int+import Data.Order.Extended import Data.Word-import Data.Connection.Ratio+import GHC.Real hiding (Fractional (..), div, (^), (^^)) import Hedgehog-import Test.Data.Connection-import qualified Data.Connection.Property as Prop import qualified Hedgehog.Gen as G+import qualified Hedgehog.Range as R+import Numeric.Natural+import Test.Data.Connection +fxx :: Gen (Extended (Fixed k))+fxx = gen_extended $ MkFixed <$> G.integral ri'++prop_connection_ratf06 :: Property+prop_connection_ratf06 = withTests 1000 . property $ do+    x <- forAll rat+    x' <- forAll rat+    y <- forAll fxx+    y' <- forAll fxx++    assert $ Prop.adjoint (ratfix @E6) x y+    assert $ Prop.closed (ratfix @E6) x+    assert $ Prop.kernel (ratfix @E6) y+    assert $ Prop.monotonic (ratfix @E6) x x' y y'+    assert $ Prop.idempotent (ratfix @E6) x y++prop_connection_ratf09 :: Property+prop_connection_ratf09 = withTests 1000 . property $ do+    x <- forAll rat+    x' <- forAll rat+    y <- forAll fxx+    y' <- forAll fxx++    assert $ Prop.adjoint (ratfix @E9) x y+    assert $ Prop.closed (ratfix @E9) x+    assert $ Prop.kernel (ratfix @E9) y+    assert $ Prop.monotonic (ratfix @E9) x x' y y'+    assert $ Prop.idempotent (ratfix @E9) x y++prop_connection_ratf12 :: Property+prop_connection_ratf12 = withTests 1000 . property $ do+    x <- forAll rat+    x' <- forAll rat+    y <- forAll fxx+    y' <- forAll fxx++    assert $ Prop.adjoint (ratfix @E12) x y+    assert $ Prop.closed (ratfix @E12) x+    assert $ Prop.kernel (ratfix @E12) y+    assert $ Prop.monotonic (ratfix @E12) x x' y y'+    assert $ Prop.idempotent (ratfix @E12) x y+ prop_connection_ratf32 :: Property prop_connection_ratf32 = withTests 1000 . property $ do-  x <- forAll rat-  x' <- forAll rat-  y <- forAll f32-  y' <- forAll f32+    x <- forAll rat'+    x' <- forAll rat'+    y <- forAll f32+    y' <- forAll f32 -  assert $ Prop.adjoint (ratf32) x y-  assert $ Prop.closed (ratf32) x-  assert $ Prop.kernel (ratf32) y-  assert $ Prop.monotonic (ratf32) x x' y y'-  assert $ Prop.idempotent (ratf32) x y+    assert $ Prop.adjoint (ratf32) x y+    assert $ Prop.closed (ratf32) x+    assert $ Prop.kernel (ratf32) y+    assert $ Prop.monotonic (ratf32) x x' y y'+    assert $ Prop.idempotent (ratf32) x y  prop_connection_ratf64 :: Property prop_connection_ratf64 = withTests 1000 . property $ do-  x <- forAll rat-  x' <- forAll rat-  y <- forAll f64-  y' <- forAll f64+    x <- forAll rat'+    x' <- forAll rat'+    y <- forAll f64+    y' <- forAll f64 -  assert $ Prop.adjoint (ratf64) x y-  assert $ Prop.closed (ratf64) x-  assert $ Prop.kernel (ratf64) y-  assert $ Prop.monotonic (ratf64) x x' y y'-  assert $ Prop.idempotent (ratf64) x y+    assert $ Prop.adjoint (ratf64) x y+    assert $ Prop.closed (ratf64) x+    assert $ Prop.kernel (ratf64) y+    assert $ Prop.monotonic (ratf64) x x' y y'+    assert $ Prop.idempotent (ratf64) x y  prop_connection_rati08 :: Property prop_connection_rati08 = withTests 1000 . property $ do-  x <- forAll rat-  x' <- forAll rat-  y <- forAll $ gen_extended $ G.integral (ri @Int8)-  y' <- forAll $ gen_extended $ G.integral (ri @Int8)+    x <- forAll rat'+    x' <- forAll rat'+    y <- forAll $ gen_extended $ G.integral (ri @Int8)+    y' <- forAll $ gen_extended $ G.integral (ri @Int8) -  assert $ Prop.adjoint (rati08) x y-  assert $ Prop.closed (rati08) x-  assert $ Prop.kernel (rati08) y-  assert $ Prop.monotonic (rati08) x x' y y'-  assert $ Prop.idempotent (rati08) x y+    assert $ Prop.adjoint (rati08) x y+    assert $ Prop.closed (rati08) x+    assert $ Prop.kernel (rati08) y+    assert $ Prop.monotonic (rati08) x x' y y'+    assert $ Prop.idempotent (rati08) x y  prop_connection_rati16 :: Property prop_connection_rati16 = withTests 1000 . property $ do-  x <- forAll rat-  x' <- forAll rat-  y <- forAll $ gen_extended $ G.integral (ri @Int16)-  y' <- forAll $ gen_extended $ G.integral (ri @Int16)+    x <- forAll rat'+    x' <- forAll rat'+    y <- forAll $ gen_extended $ G.integral (ri @Int16)+    y' <- forAll $ gen_extended $ G.integral (ri @Int16) -  assert $ Prop.adjoint (rati16) x y-  assert $ Prop.closed (rati16) x-  assert $ Prop.kernel (rati16) y-  assert $ Prop.monotonic (rati16) x x' y y'-  assert $ Prop.idempotent (rati16) x y+    assert $ Prop.adjoint (rati16) x y+    assert $ Prop.closed (rati16) x+    assert $ Prop.kernel (rati16) y+    assert $ Prop.monotonic (rati16) x x' y y'+    assert $ Prop.idempotent (rati16) x y  prop_connection_rati32 :: Property prop_connection_rati32 = withTests 1000 . property $ do-  x <- forAll rat-  x' <- forAll rat-  y <- forAll $ gen_extended $ G.integral (ri @Int32)-  y' <- forAll $ gen_extended $ G.integral (ri @Int32)+    x <- forAll rat'+    x' <- forAll rat'+    y <- forAll $ gen_extended $ G.integral (ri @Int32)+    y' <- forAll $ gen_extended $ G.integral (ri @Int32) -  assert $ Prop.adjoint (rati32) x y-  assert $ Prop.closed (rati32) x-  assert $ Prop.kernel (rati32) y-  assert $ Prop.monotonic (rati32) x x' y y'-  assert $ Prop.idempotent (rati32) x y+    assert $ Prop.adjoint (rati32) x y+    assert $ Prop.closed (rati32) x+    assert $ Prop.kernel (rati32) y+    assert $ Prop.monotonic (rati32) x x' y y'+    assert $ Prop.idempotent (rati32) x y  prop_connection_rati64 :: Property prop_connection_rati64 = withTests 1000 . property $ do-  x <- forAll rat-  x' <- forAll rat-  y <- forAll $ gen_extended $ G.integral (ri @Int64)-  y' <- forAll $ gen_extended $ G.integral (ri @Int64)+    x <- forAll rat'+    x' <- forAll rat'+    y <- forAll $ gen_extended $ G.integral (ri @Int64)+    y' <- forAll $ gen_extended $ G.integral (ri @Int64) -  assert $ Prop.adjoint (rati64) x y-  assert $ Prop.closed (rati64) x-  assert $ Prop.kernel (rati64) y-  assert $ Prop.monotonic (rati64) x x' y y'-  assert $ Prop.idempotent (rati64) x y+    assert $ Prop.adjoint (rati64) x y+    assert $ Prop.closed (rati64) x+    assert $ Prop.kernel (rati64) y+    assert $ Prop.monotonic (rati64) x x' y y'+    assert $ Prop.idempotent (rati64) x y  prop_connection_ratint :: Property prop_connection_ratint = withTests 1000 . property $ do-  x <- forAll rat-  x' <- forAll rat-  y <- forAll $ gen_extended $ G.integral ri'-  y' <- forAll $ gen_extended $ G.integral ri'+    x <- forAll rat'+    x' <- forAll rat'+    y <- forAll $ gen_extended $ G.integral ri'+    y' <- forAll $ gen_extended $ G.integral ri' -  assert $ Prop.adjoint (ratint) x y-  assert $ Prop.closed (ratint) x-  assert $ Prop.kernel (ratint) y-  assert $ Prop.monotonic (ratint) x x' y y'-  assert $ Prop.idempotent (ratint) x y+    assert $ Prop.adjoint (ratint) x y+    assert $ Prop.closed (ratint) x+    assert $ Prop.kernel (ratint) y+    assert $ Prop.monotonic (ratint) x x' y y'+    assert $ Prop.idempotent (ratint) x y  prop_connection_posw08 :: Property prop_connection_posw08 = withTests 1000 . property $ do-  x <- forAll pos-  x' <- forAll pos-  y <- forAll $ gen_lowered $ G.integral (ri @Word8)-  y' <- forAll $ gen_lowered $ G.integral (ri @Word8)+    x <- forAll pos+    x' <- forAll pos+    y <- forAll $ gen_lowered $ G.integral (ri @Word8)+    y' <- forAll $ gen_lowered $ G.integral (ri @Word8) -  assert $ Prop.adjoint (posw08) x y-  assert $ Prop.closed (posw08) x-  assert $ Prop.kernel (posw08) y-  assert $ Prop.monotonic (posw08) x x' y y'-  assert $ Prop.idempotent (posw08) x y+    assert $ Prop.adjoint (posw08) x y+    assert $ Prop.closed (posw08) x+    assert $ Prop.kernel (posw08) y+    assert $ Prop.monotonic (posw08) x x' y y'+    assert $ Prop.idempotent (posw08) x y  prop_connection_posw16 :: Property prop_connection_posw16 = withTests 1000 . property $ do-  x <- forAll pos-  x' <- forAll pos-  y <- forAll $ gen_lowered $ G.integral (ri @Word16)-  y' <- forAll $ gen_lowered $ G.integral (ri @Word16)+    x <- forAll pos+    x' <- forAll pos+    y <- forAll $ gen_lowered $ G.integral (ri @Word16)+    y' <- forAll $ gen_lowered $ G.integral (ri @Word16) -  assert $ Prop.adjoint (posw16) x y-  assert $ Prop.closed (posw16) x-  assert $ Prop.kernel (posw16) y-  assert $ Prop.monotonic (posw16) x x' y y'-  assert $ Prop.idempotent (posw16) x y+    assert $ Prop.adjoint (posw16) x y+    assert $ Prop.closed (posw16) x+    assert $ Prop.kernel (posw16) y+    assert $ Prop.monotonic (posw16) x x' y y'+    assert $ Prop.idempotent (posw16) x y  prop_connection_posw32 :: Property prop_connection_posw32 = withTests 1000 . property $ do-  x <- forAll pos-  x' <- forAll pos-  y <- forAll $ gen_lowered $ G.integral (ri @Word32)-  y' <- forAll $ gen_lowered $ G.integral (ri @Word32)+    x <- forAll pos+    x' <- forAll pos+    y <- forAll $ gen_lowered $ G.integral (ri @Word32)+    y' <- forAll $ gen_lowered $ G.integral (ri @Word32) -  assert $ Prop.adjoint (posw32) x y-  assert $ Prop.closed (posw32) x-  assert $ Prop.kernel (posw32) y-  assert $ Prop.monotonic (posw32) x x' y y'-  assert $ Prop.idempotent (posw32) x y+    assert $ Prop.adjoint (posw32) x y+    assert $ Prop.closed (posw32) x+    assert $ Prop.kernel (posw32) y+    assert $ Prop.monotonic (posw32) x x' y y'+    assert $ Prop.idempotent (posw32) x y  prop_connection_posw64 :: Property prop_connection_posw64 = withTests 1000 . property $ do-  x <- forAll pos-  x' <- forAll pos-  y <- forAll $ gen_lowered $ G.integral (ri @Word64)-  y' <- forAll $ gen_lowered $ G.integral (ri @Word64)+    x <- forAll pos+    x' <- forAll pos+    y <- forAll $ gen_lowered $ G.integral (ri @Word64)+    y' <- forAll $ gen_lowered $ G.integral (ri @Word64) -  assert $ Prop.adjoint (posw64) x y-  assert $ Prop.closed (posw64) x-  assert $ Prop.kernel (posw64) y-  assert $ Prop.monotonic (posw64) x x' y y'-  assert $ Prop.idempotent (posw64) x y+    assert $ Prop.adjoint (posw64) x y+    assert $ Prop.closed (posw64) x+    assert $ Prop.kernel (posw64) y+    assert $ Prop.monotonic (posw64) x x' y y'+    assert $ Prop.idempotent (posw64) x y  prop_connection_posnat :: Property prop_connection_posnat = withTests 1000 . property $ do-  x <- forAll pos-  x' <- forAll pos-  y <- forAll $ gen_lowered $ G.integral rn-  y' <- forAll $ gen_lowered $ G.integral rn+    x <- forAll pos+    x' <- forAll pos+    y <- forAll $ gen_lowered $ G.integral rn+    y' <- forAll $ gen_lowered $ G.integral rn -  assert $ Prop.adjoint (posnat) x y-  assert $ Prop.closed (posnat) x-  assert $ Prop.kernel (posnat) y-  assert $ Prop.monotonic (posnat) x x' y y'-  assert $ Prop.idempotent (posnat) x y+    assert $ Prop.adjoint (posnat) x y+    assert $ Prop.closed (posnat) x+    assert $ Prop.kernel (posnat) y+    assert $ Prop.monotonic (posnat) x x' y y'+    assert $ Prop.idempotent (posnat) x y  tests :: IO Bool tests = checkParallel $$(discover)
test/Test/Data/Order.hs view
@@ -250,10 +250,10 @@  prop_order_rat :: Property prop_order_rat = withTests 1000 . property $ do-  x <- forAll rat-  y <- forAll rat-  z <- forAll rat-  w <- forAll rat+  x <- forAll rat'+  y <- forAll rat'+  z <- forAll rat'+  w <- forAll rat'   assert $ Prop.preorder x y   assert $ Prop.order z w   assert $ Prop.reflexive_eq x
test/test.hs view
@@ -3,6 +3,7 @@ import System.IO (BufferMode (..), hSetBuffering, stderr, stdout)  import qualified Test.Data.Connection as C+import qualified Test.Data.Connection.Fixed as CX import qualified Test.Data.Connection.Float as CF import qualified Test.Data.Connection.Int as CI import qualified Test.Data.Connection.Ratio as CR@@ -19,6 +20,7 @@         , CI.tests         , CW.tests         , CF.tests+        , CX.tests         , CR.tests         ]