module Data.Interval (Interval (..), (∪), (∩)) where import Prelude hiding (Eq, Ord (..), max, min) import Control.Applicative import Data.Function (on) import Data.Ord (Down (..)) import Relation.Binary.Comparison infix 5 :–: data Interval a = Maybe a :–: Maybe a deriving (Read, Show, Functor, Foldable, Traversable) instance Preord a => Preord (Interval a) where a₁ :–: b₁ ≤ a₂ :–: b₂ = Lexical a₁ ≤ Lexical b₁ && ((≥) `on` Down . Lexical . fmap Down) a₂ b₂ instance PartialEq a => PartialEq (Interval a) where a₁ :–: b₁ ≡ a₂ :–: b₂ = (a₁, b₁) ≡ (a₂, b₂) instance (PartialOrd a, PartialEq a) => PartialOrd (Interval a) instance Eq a => Eq (Interval a) infixr 4 ∪, ∩ (∪), (∩) :: Ord a => Interval a -> Interval a -> Interval a a₁ :–: b₁ ∪ a₂ :–: b₂ = liftA2 min a₁ a₂ :–: liftA2 max b₁ b₂ a₁ :–: b₁ ∩ a₂ :–: b₂ = fmap unMax (fmap Max a₁ <> fmap Max a₂) :–: fmap unMin (fmap Min b₁ <> fmap Min b₂)