packages feed

interval-patterns 0.7.0.2 → 0.7.0.3

raw patch · 3 files changed

+228/−191 lines, 3 filesdep ~latticesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: lattices

API changes (from Hackage documentation)

- Data.Interval: [:<-->:] :: Ord x => !Bound Infimum (Levitated x) -> !Bound Supremum (Levitated x) -> Interval x
- Data.Interval: [:<--|:] :: Ord x => !Bound Infimum (Levitated x) -> !Bound Maximum (Levitated x) -> Interval x
- Data.Interval: [:|-->:] :: Ord x => !Bound Minimum (Levitated x) -> !Bound Supremum (Levitated x) -> Interval x
- Data.Interval: [:|--|:] :: Ord x => !Bound Minimum (Levitated x) -> !Bound Maximum (Levitated x) -> Interval x
- Data.Interval: infix 5 :||:
+ Data.Interval: infix 5 :|-|:

Files

CHANGELOG.md view
@@ -1,5 +1,14 @@ # Revision history for interval-patterns +## 0.7.0.3++* update `lattice` version range to build on new stackage LTS++## 0.7.0.2++* fix bug in `Data.Interval.hull`+* improve documentation of `Data.Interval`+ ## 0.7.0.1  * use `heaps` to improve performance of `Layers` at the cost of an `Ord` constraint on the "height" of the layers
interval-patterns.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               interval-patterns-version:            0.7.0.2+version:            0.7.0.3 author:             Melanie Brown synopsis:           Intervals, and monoids thereof category:           Algebra, Charts, Data Structures, Math, Statistics@@ -20,49 +20,26 @@     , containers     , groups       >=0.5.3   && <0.6     , heaps        >=0.4     && <0.5-    , lattices     >=2.0.3   && <2.1+    , lattices     >=2.1     && <3     , semirings    >=0.6     && <0.7     , time     , time-compat  >=1.9.6.1 && <1.10 +  default-language:   GHC2021   default-extensions:-    BangPatterns-    ConstraintKinds+    BlockArguments     DataKinds-    DeriveDataTypeable-    DeriveFoldable-    DeriveFunctor-    DeriveGeneric-    DeriveLift-    DeriveTraversable+    DefaultSignatures     DerivingStrategies-    DerivingVia-    EmptyCase-    FlexibleContexts-    FlexibleInstances-    FunctionalDependencies-    GADTs-    GeneralizedNewtypeDeriving-    ImportQualifiedPost     LambdaCase-    MultiParamTypeClasses     MultiWayIf-    NamedFieldPuns     OverloadedStrings     PatternSynonyms-    PolyKinds     QuasiQuotes     RecordWildCards-    ScopedTypeVariables-    StandaloneDeriving-    StandaloneKindSignatures-    TupleSections-    TypeApplications     TypeFamilies-    TypeOperators     ViewPatterns -  default-language:   Haskell2010   ghc-options:        -Wall -Wcompat -Wno-unticked-promoted-constructors  library
src/Data/Interval.hs view
@@ -1,51 +1,56 @@ -- | -- Module       : Data.Interval--- Copyright    : (c) Melanie Brown 2022--- License:     : BSD3 (see the file LICENSE)+-- Copyright    : (c) Melanie Brown 2023+-- License      : BSD3 (see the file LICENSE) -- -- Intervals over types and their operations. module Data.Interval (-  Extremum (..),-  opposite,-  Bound (..),-  unBound,-  Bounding (..),-  compareBounds,-  SomeBound (..),-  unSomeBound,-  oppose,-  Interval (..),-  imap,-  imapLev,-  itraverse,-  itraverseLev,-  pattern (:<->:),-  pattern (:<-|:),-  pattern (:|->:),-  pattern (:|-|:),-  pattern (:---:),+  -- * The Interval type+  Interval,++  -- ** Construction++  -- *** Finite intervals   pattern (:<>:),   pattern (:<|:),   pattern (:|>:),   pattern (:||:),   pattern (:--:),++  -- *** Possibly-infinite intervals++  -- |+  -- The first four form a @{-# COMPLETE #-}@ set of bidirectional patterns,+  -- and the final is a @{-# COMPLETE #-}@ unidirectional pattern on its own.+  pattern (:<->:),+  pattern (:<-|:),+  pattern (:|->:),+  pattern (:|-|:),+  pattern (:---:),++  -- *** Miscellaneous constructors   pattern Whole,   (+/-),   (...),+  interval,+  point,++  -- ** Deconstruction   bounds,   lower,   lowerBound,   upper,   upperBound,-  interval,   imin,   iinf,   isup,   imax,-  hull,-  hulls,-  within,-  point,++  -- ** Modification+  imap,+  imapLev,+  itraverse,+  itraverseLev,   open,   close,   openclosed,@@ -56,7 +61,12 @@   closedUpper,   setLower,   setUpper,++  -- * Computing with intervals   Adjacency (..),+  hull,+  hulls,+  within,   converseAdjacency,   adjacency,   intersect,@@ -71,6 +81,19 @@   measuring,   hausdorff,   isSubsetOf,++  -- * Bounds+  Extremum (..),+  opposite,+  Bound (..),+  unBound,+  Bounding (..),+  compareBounds,+  SomeBound (..),+  unSomeBound,+  oppose,++  -- * Re-exports   OneOrTwo (..), ) where @@ -125,6 +148,7 @@   Max x -> x  instance Functor (Bound ext) where+  fmap :: (a -> b) -> Bound ext a -> Bound ext b   fmap f = \case     Min x -> Min (f x)     Inf x -> Inf (f x)@@ -132,6 +156,7 @@     Max x -> Max (f x)  instance Foldable (Bound ext) where+  foldMap :: (Monoid m) => (a -> m) -> Bound ext a -> m   foldMap f = \case     Min x -> f x     Inf x -> f x@@ -139,6 +164,7 @@     Max x -> f x  instance Traversable (Bound ext) where+  traverse :: (Applicative f) => (a -> f b) -> Bound ext a -> f (Bound ext b)   traverse f = \case     Min x -> Min <$> f x     Inf x -> Inf <$> f x@@ -146,18 +172,22 @@     Max x -> Max <$> f x  instance (Eq x) => Eq (Bound ext x) where+  (==) :: (Eq x) => Bound ext x -> Bound ext x -> Bool   Min x == Min y = x == y   Inf x == Inf y = x == y   Sup x == Sup y = x == y   Max x == Max y = x == y  instance (Ord x) => Ord (Bound ext (Levitated x)) where+  compare ::+    (Ord x) => Bound ext (Levitated x) -> Bound ext (Levitated x) -> Ordering   compare = compareBounds  -- | A type class for inverting 'Bound's. type Bounding :: Extremum -> Constraint class (Opposite (Opposite ext) ~ ext) => Bounding ext where   type Opposite ext :: Extremum+   bound :: x -> Bound ext x    -- | c.f. 'opposite'.@@ -165,35 +195,51 @@  instance Bounding Minimum where   type Opposite Minimum = Supremum++  bound :: x -> Bound Minimum x   bound = Min++  opposeBound :: Bound Minimum x -> Bound Supremum x   opposeBound (Min x) = Sup x  instance Bounding Infimum where   type Opposite Infimum = Maximum++  bound :: x -> Bound Infimum x   bound = Inf++  opposeBound :: Bound Infimum x -> Bound Maximum x   opposeBound (Inf x) = Max x  instance Bounding Supremum where   type Opposite Supremum = Minimum++  bound :: x -> Bound Supremum x   bound = Sup++  opposeBound :: Bound Supremum x -> Bound Minimum x   opposeBound (Sup x) = Min x  instance Bounding Maximum where   type Opposite Maximum = Infimum++  bound :: x -> Bound Maximum x   bound = Max++  opposeBound :: Bound Maximum x -> Bound Infimum x   opposeBound (Max x) = Inf x  -- | 'Bound's have special comparison rules for identical points. ----- >>> compareBounds (Min (Levitate 5)) (Max (Levitate 5))+-- >>> compareBounds (Min (Levitate 0)) (Max (Levitate 0)) -- EQ--- >>> compareBounds (Inf (Levitate 5)) (Sup (Levitate 5))+-- >>> compareBounds (Inf (Levitate 0)) (Sup (Levitate 0)) -- GT--- >>> compareBounds (Max (Levitate 5)) (Sup (Levitate 5))+-- >>> compareBounds (Max (Levitate 0)) (Sup (Levitate 0)) -- GT--- >>> compareBounds (Inf (Levitate 5)) (Min (Levitate 5))+-- >>> compareBounds (Inf (Levitate 0)) (Min (Levitate 0)) -- GT--- >>> compareBounds (Max (Levitate 5)) (Inf (Levitate 5))+-- >>> compareBounds (Max (Levitate 0)) (Inf (Levitate 0)) -- LT compareBounds ::   (Ord x) =>@@ -227,6 +273,7 @@     SomeBound !(Bound ext x)  instance (Eq x) => Eq (SomeBound (Levitated x)) where+  (==) :: (Eq x) => SomeBound (Levitated x) -> SomeBound (Levitated x) -> Bool   SomeBound (Min a) == SomeBound (Min b) = a == b   SomeBound (Max a) == SomeBound (Max b) = a == b   SomeBound (Inf a) == SomeBound (Inf b) = a == b@@ -234,6 +281,8 @@   _ == _ = False  instance (Ord x) => Ord (SomeBound (Levitated x)) where+  compare ::+    (Ord x) => SomeBound (Levitated x) -> SomeBound (Levitated x) -> Ordering   SomeBound b0 `compare` SomeBound b1 = compareBounds b0 b1  oppose :: SomeBound x -> SomeBound x@@ -252,25 +301,25 @@  type Interval :: Type -> Type data Interval x where-  -- Open-open interval. You probably want '(:<->:)' or '(:<>:)'.+  -- | Open-open interval. You probably want '(:<->:)' or '(:<>:)'.   (:<-->:) ::     (Ord x) =>     !(Bound Infimum (Levitated x)) ->     !(Bound Supremum (Levitated x)) ->     Interval x-  -- Open-closed interval. You probably want '(:<-|:)' or '(:<|:)'.+  -- | Open-closed interval. You probably want '(:<-|:)' or '(:<|:)'.   (:<--|:) ::     (Ord x) =>     !(Bound Infimum (Levitated x)) ->     !(Bound Maximum (Levitated x)) ->     Interval x-  -- Closed-open interval. You probably want '(:|->:)' or '(:|>:)'.+  -- | Closed-open interval. You probably want '(:|->:)' or '(:|>:)'.   (:|-->:) ::     (Ord x) =>     !(Bound Minimum (Levitated x)) ->     !(Bound Supremum (Levitated x)) ->     Interval x-  -- Closed-closed interval. You probably want '(:|-|:)' or '(:||:)'.+  -- | Closed-closed interval. You probably want '(:|-|:)' or '(:||:)'.   (:|--|:) ::     (Ord x) =>     !(Bound Minimum (Levitated x)) ->@@ -401,13 +450,14 @@       (SomeBound (unBound -> Levitate l), SomeBound (unBound -> Levitate u))     ) --- | The whole interval.+-- | The whole interval, 'Bottom' ':|-|:' 'Top'. pattern Whole :: (Ord x) => Interval x pattern Whole = Bottom :|-|: Top  deriving instance (Ord x) => Eq (Interval x)  instance (Ord x, Show x) => Show (Interval x) where+  show :: (Ord x, Show x) => Interval x -> String   show = \case     l :<>: u -> "(" <> show l <> " :<>: " <> show u <> ")"     l :|>: u -> "(" <> show l <> " :|>: " <> show u <> ")"@@ -419,20 +469,38 @@     l :|-|: u -> "(" <> show l <> " :|-|: " <> show u <> ")"  instance (Ord x) => Ord (Interval x) where+  compare :: (Ord x) => Interval x -> Interval x -> Ordering   compare i1 i2 = on compare lower i1 i2 <> on compare upper i1 i2  instance (Ord x, Data x) => Data (Interval x) where+  gfoldl ::+    (Ord x, Data x) =>+    (forall d b. (Data d) => c (d -> b) -> d -> c b) ->+    (forall g. g -> c g) ->+    Interval x ->+    c (Interval x)   gfoldl (<^>) gpure = \case     l :<->: u -> gpure (:<->:) <^> l <^> u     l :|->: u -> gpure (:|->:) <^> l <^> u     l :<-|: u -> gpure (:<-|:) <^> l <^> u     l :|-|: u -> gpure (:|-|:) <^> l <^> u++  toConstr :: (Ord x, Data x) => Interval x -> Constr   toConstr = \case     _ :<->: _ -> intervalOpenOpenConstr     _ :|->: _ -> intervalClosedOpenConstr     _ :<-|: _ -> intervalOpenClosedConstr     _ :|-|: _ -> intervalClosedClosedConstr++  dataTypeOf :: (Ord x, Data x) => Interval x -> DataType   dataTypeOf _ = intervalDataType++  gunfold ::+    (Ord x, Data x) =>+    (forall b r. (Data b) => c (b -> r) -> c r) ->+    (forall r. r -> c r) ->+    Constr ->+    c (Interval x)   gunfold k gpure constr = case constrIndex constr of     0 -> k (k (gpure (:<->:)))     1 -> k (k (gpure (:|->:)))@@ -482,15 +550,21 @@     , intervalClosedClosedConstr     ] -deriving instance Typeable x => Typeable (Interval x)+deriving instance (Typeable x) => Typeable (Interval x)  instance (Ord x, Generic x) => Generic (Interval x) where-  type Rep (Interval x) = (Const (Levitated x, Extremum) :*: Const (Levitated x, Extremum))+  type+    Rep (Interval x) =+      (Const (Levitated x, Extremum) :*: Const (Levitated x, Extremum))++  from :: (Ord x, Generic x) => Interval x -> Rep (Interval x) x1   from = \case     l :<->: u -> (Const (l, Infimum) :*: Const (u, Supremum))     l :|->: u -> (Const (l, Minimum) :*: Const (u, Supremum))     l :<-|: u -> (Const (l, Infimum) :*: Const (u, Maximum))     l :|-|: u -> (Const (l, Minimum) :*: Const (u, Maximum))++  to :: (Ord x, Generic x) => Rep (Interval x) x1 -> Interval x   to (Const l :*: Const u) = l ... u  -- | Since the 'Ord' constraints on the constructors for 'Interval'@@ -539,9 +613,7 @@   l :<-|: u -> liftA2 (:<-|:) (f l) (f u)   l :|-|: u -> liftA2 (:|-|:) (f l) (f u) --- | Get the @(lower, upper)@ 'bounds' of an 'Interval'.------ c.f. 'lower', 'upper'.+-- | Get the @('lower', 'upper')@ bounds of an 'Interval'. bounds :: Interval x -> (SomeBound (Levitated x), SomeBound (Levitated x)) bounds = \case   l :<-->: u -> (SomeBound l, SomeBound u)@@ -654,6 +726,69 @@   MetBy i j k -> Meets i j k   After i j -> Before i j +-- | Calculate the 'Adjacency' between two intervals, according to+-- [Allen](https://en.wikipedia.org/wiki/Allen%27s_interval_algebra).+adjacency :: (Ord x) => Interval x -> Interval x -> Adjacency x+adjacency i1 i2 = case (comparing lower i1 i2, comparing upper i1 i2) of+  (LT, LT) -> case unSomeBound ub1 `compare` unSomeBound lb2 of+    LT -> Before i1 i2+    EQ -> case (ub1, lb2) of+      (SomeBound (Max _), SomeBound (Min _)) ->+        Meets+          (openUpper i1)+          (interval lb2 ub1)+          (openLower i2)+      _ -> Before i1 i2+    GT ->+      Overlaps+        (interval lb1 (oppose lb2))+        (interval lb2 ub1)+        (interval (oppose ub1) ub2)+  (LT, EQ) ->+    Finishes+      (interval lb1 (oppose lb2))+      i2+  (LT, GT) ->+    Contains+      (interval lb1 (oppose lb2))+      (interval lb2 ub2)+      (interval (oppose ub2) ub1)+  (EQ, LT) ->+    Starts+      i1+      (interval (oppose ub1) ub2)+  (EQ, EQ) -> Identical i1+  (EQ, GT) ->+    StartedBy+      i2+      (interval (oppose ub2) ub1)+  (GT, LT) ->+    During+      (interval lb2 (oppose lb1))+      (interval lb1 ub1)+      (interval (oppose ub1) ub2)+  (GT, EQ) ->+    FinishedBy+      (interval lb2 (oppose lb1))+      i1+  (GT, GT) -> case unSomeBound ub2 `compare` unSomeBound lb1 of+    GT ->+      OverlappedBy+        (interval lb2 (oppose lb1))+        (interval lb1 ub2)+        (interval (oppose ub2) ub1)+    EQ -> case (ub2, lb1) of+      (SomeBound (Max _), SomeBound (Min _)) ->+        MetBy+          (openUpper i2)+          (interval lb1 ub2)+          (openLower i1)+      _ -> After i2 i1+    LT -> After i2 i1+ where+  (lb1, ub1) = bounds i1+  (lb2, ub2) = bounds i2+ -- | Get the convex hull of two intervals. -- -- >>> hull (7 :|>: 8) (3 :|>: 4)@@ -663,24 +798,24 @@ -- (Bottom :<->: Levitate 5) hull :: (Ord x) => Interval x -> Interval x -> Interval x hull i1 i2 = case adjacency i1 i2 of-  Before i j -> lowerBound i ... upperBound j-  Meets i _ k -> lowerBound i ... upperBound k-  Overlaps i _ k -> lowerBound i ... upperBound k-  Starts i j -> lowerBound i ... upperBound j-  During i _ k -> lowerBound i ... upperBound k-  Finishes i j -> lowerBound i ... upperBound j+  Before i j -> interval (lower i) (upper j)+  Meets i _ k -> interval (lower i) (upper k)+  Overlaps i _ k -> interval (lower i) (upper k)+  Starts i j -> interval (lower i) (upper j)+  During i _ k -> interval (lower i) (upper k)+  Finishes i j -> interval (lower i) (upper j)   Identical i -> i-  FinishedBy i j -> lowerBound i ... upperBound j-  Contains i _ k -> lowerBound i ... upperBound k-  StartedBy i j -> lowerBound i ... upperBound j-  OverlappedBy i _ k -> lowerBound i ... upperBound k-  MetBy i _ k -> lowerBound i ... upperBound k-  After i j -> lowerBound i ... upperBound j+  FinishedBy i j -> interval (lower i) (upper j)+  Contains i _ k -> interval (lower i) (upper k)+  StartedBy i j -> interval (lower i) (upper j)+  OverlappedBy i _ k -> interval (lower i) (upper k)+  MetBy i _ k -> interval (lower i) (upper k)+  After i j -> interval (lower i) (upper j)  -- | Get the convex hull of a non-empty list of intervals. hulls :: (Ord x) => NonEmpty (Interval x) -> Interval x hulls (i :| []) = i-hulls (i :| j : is) = hulls $ hull i j :| is+hulls (i :| j : is) = hulls (hull i j :| is)  -- | Test whether a point is contained in the interval. within :: (Ord x) => x -> Interval x -> Bool@@ -705,7 +840,7 @@   (x :|-|: _) -> Just x   _ -> Nothing --- | Get the maximum of an interval if it exists.+-- | Get the maximum of an interval, if it exists. imax :: (Ord x) => Interval x -> Maybe (Levitated x) imax = \case   (_ :<-|: x) -> Just x@@ -778,73 +913,9 @@   l :|->: _ -> l :|->: x   l :|-|: _ -> l :|-|: x --- | Calculate the 'Adjacency' between two intervals, according to--- [Allen](https://en.wikipedia.org/wiki/Allen%27s_interval_algebra).-adjacency :: (Ord x) => Interval x -> Interval x -> Adjacency x-adjacency i1 i2 = case (comparing lower i1 i2, comparing upper i1 i2) of-  (LT, LT) -> case unSomeBound ub1 `compare` unSomeBound lb2 of-    LT -> Before i1 i2-    EQ -> case (ub1, lb2) of-      (SomeBound (Max _), SomeBound (Min _)) ->-        Meets-          (openUpper i1)-          (interval lb2 ub1)-          (openLower i2)-      _ -> Before i1 i2-    GT ->-      Overlaps-        (interval lb1 (oppose lb2))-        (interval lb2 ub1)-        (interval (oppose ub1) ub2)-  (LT, EQ) ->-    Finishes-      (interval lb1 (oppose lb2))-      i2-  (LT, GT) ->-    Contains-      (interval lb1 (oppose lb2))-      (interval lb2 ub2)-      (interval (oppose ub2) ub1)-  (EQ, LT) ->-    Starts-      i1-      (interval (oppose ub1) ub2)-  (EQ, EQ) -> Identical i1-  (EQ, GT) ->-    StartedBy-      i2-      (interval (oppose ub2) ub1)-  (GT, LT) ->-    During-      (interval lb2 (oppose lb1))-      (interval lb1 ub1)-      (interval (oppose ub1) ub2)-  (GT, EQ) ->-    FinishedBy-      (interval lb2 (oppose lb1))-      i1-  (GT, GT) -> case unSomeBound ub2 `compare` unSomeBound lb1 of-    GT ->-      OverlappedBy-        (interval lb2 (oppose lb1))-        (interval lb1 ub2)-        (interval (oppose ub2) ub1)-    EQ -> case (ub2, lb1) of-      (SomeBound (Max _), SomeBound (Min _)) ->-        MetBy-          (openUpper i2)-          (interval lb1 ub2)-          (openLower i1)-      _ -> After i2 i1-    LT -> After i2 i1- where-  (lb1, ub1) = bounds i1-  (lb2, ub2) = bounds i2- -- | Calculate the intersection of two intervals, if it exists. -- -- @--- -- >>> intersect (2 :<>: 4) (3 :||: 5) -- Just (3 :|>: 4) --@@ -853,7 +924,6 @@ -- -- >>> intersect (1 :<>: 4) (2 :||: 3) -- Just (2 :||: 3)--- -- @ intersect ::   forall x.@@ -879,13 +949,11 @@ -- | Get the union of two intervals, as either 'OneOrTwo'. -- -- @--- -- >>> union (2 :||: 5) (5 :<>: 7)--- One (Levitate 2 :|->: Levitate 7)+-- One (2 :|>: 7) -- -- >>> union (2 :||: 4) (5 :<>: 7)--- Two (Levitate 2 :|-|: Levitate 4) (Levitate 5 :<->: Levitate 7)---+-- Two (2 :||: 4) (5 :<>: 7) -- @ union ::   forall x.@@ -895,21 +963,21 @@   OneOrTwo (Interval x) union i1 i2 = case adjacency i1 i2 of   Before i j-    | fst (upperBound i) == fst (lowerBound j) -> One $ hull i j+    | fst (upperBound i) == fst (lowerBound j) -> One (hull i j)     | otherwise -> Two i j-  Meets i _ k -> One $ hull i k-  Overlaps i _ k -> One $ hull i k-  Starts i j -> One $ hull i j-  During i _ k -> One $ hull i k-  Finishes i j -> One $ hull i j+  Meets i _ k -> One (hull i k)+  Overlaps i _ k -> One (hull i k)+  Starts i j -> One (hull i j)+  During i _ k -> One (hull i k)+  Finishes i j -> One (hull i j)   Identical i -> One i-  FinishedBy i j -> One $ hull i j-  Contains i _ k -> One $ hull i k-  StartedBy i j -> One $ hull i j-  OverlappedBy i _ k -> One $ hull i k-  MetBy i _ k -> One $ hull i k+  FinishedBy i j -> One (hull i j)+  Contains i _ k -> One (hull i k)+  StartedBy i j -> One (hull i j)+  OverlappedBy i _ k -> One (hull i k)+  MetBy i _ k -> One (hull i k)   After i j-    | fst (upperBound i) == fst (lowerBound j) -> One $ hull i j+    | fst (upperBound i) == fst (lowerBound j) -> One (hull i j)     | otherwise -> Two i j  -- | /O(n log n)/. Get the union of a list of intervals.@@ -931,20 +999,15 @@ -- | Take the complement of the interval, as possibly 'OneOrTwo'. -- -- @--- -- >>> complement (3 :<>: 4) -- Just (Two (Bottom :|-|: Levitate 3) (Levitate 4 :|-|: Top))--- -- @ ----- Note that infinitely-open intervals will return the points at infinity--- toward which they are infinite in their result:---+-- Note that infinitely-open intervals will include in their result+-- the points at infinity toward which they are infinite: -- @--- -- >>> complement (Levitate 3 :<->: Top) -- Just (Two (Bottom :|-|: Levitate 3) (Top :|-|: Top))--- -- @ complement ::   forall x.@@ -971,19 +1034,17 @@ -- | Remove all points of the second interval from the first. -- -- @--- -- >>> difference Whole (3 :<>: 4) -- Just (Two (Bottom :|-|: Levitate 3) (Levitate 4 :|-|: Top)) ----- >>> difference (1 :<>: 4) (2 :||: 3)--- Just (Two (1 :<>: 2) (3 :<>: 4))+-- >>> difference (1 :<>: 4) (2 :||: 5)+-- Just (One (1 :<>: 2)) -- -- >>> difference (1 :|>: 4) (0 :||: 1) -- Just (One (1 :<>: 4)) -- -- >>> difference (1 :<>: 4) (0 :||: 1) -- Just (One (1 :<>: 4))--- -- @ difference ::   forall x.@@ -1019,13 +1080,11 @@ -- | The difference of the union and intersection of two intervals. -- -- @--- -- >>> symmetricDifference Whole (3 :<>: 4) -- Just (Two (Bottom :|-|: Levitate 3) (Levitate 4 :|-|: Top)) ----- >>> symmetricDifference (1 :<>: 4) (2 :||: 3)--- Just (Two (1 :<>: 2) (3 :<>: 4))---+-- >>> symmetricDifference (1 :<>: 4) (2 :||: 5)+-- Just (Two (1 :<>: 2) (4 :||: 5)) -- @ symmetricDifference ::   forall x.@@ -1039,16 +1098,14 @@     Nothing -> Just (One u)     Just i -> difference u i --- | Get the measure of an interval.+-- | Get the measure of an interval, or 'Nothing' if the interval is infinite. -- -- @--- -- >>> measure (-1 :<>: 1) -- Just 2 -- -- >>> measure (Bottom :<->: Levitate 1) -- Nothing--- -- @ measure :: forall x. (Ord x, Num x) => Interval x -> Maybe x measure = measuring subtract@@ -1056,17 +1113,13 @@ -- | Apply a function to the lower, then upper, endpoint of an interval. -- -- @------ >>> measuring max (-1 :<>: 1)--- Just 1------ >>> measuring min (-1 :<>: 1)+-- >>> measuring const (-1 :<>: 1) -- Just (-1) -- -- >>> measuring (*) (4 :<>: 6) -- Just 24--- -- @+-- > measure == measuring subtract measuring ::   forall y x.   (Ord x, Num y) =>@@ -1079,16 +1132,14 @@     | l == u -> Just 0     | otherwise -> Nothing --- | Get the distance between two intervals, or 0 if they adjacency.+-- | Get the distance between two intervals. -- -- @--- -- >>> hausdorff (3 :<>: 5) (6 :<>: 7) -- Just 1 -- -- >>> hausdorff (3 :<>: 5) Whole -- Just 0--- -- @ hausdorff :: (Ord x, Num x) => Interval x -> Interval x -> Maybe x hausdorff i1 i2 = case adjacency i1 i2 of