diff --git a/spago.yaml b/spago.yaml index c5aa839..91ec45b 100644 --- a/spago.yaml +++ b/spago.yaml @@ -3,22 +3,12 @@ package: strict: true pedantic_packages: true dependencies: - - prelude - - aff - - effect - - either + - enums - maybe - - foldable-traversable - - console - - newtype - - strings - - stringutils - - transformers - - tuples - - typelevel-prelude - name: project + - prelude + name: range workspace: extra_packages: {} package_set: url: https://raw.githubusercontent.com/purescript/package-sets/psc-0.15.10-20230930/packages.json - hash: sha256-nTsd44o7/hrTdk0c6dh0wyBqhFFDJJIeKdQU6L1zv/A= + hash: sha256-hp58GPoH+qX3eUsk2ecoHBZpQ50rFeZCCMTdKkYTr/Y= diff --git a/src/Data.Range.purs b/src/Data.Range.purs new file mode 100644 index 0000000..a726f3c --- /dev/null +++ b/src/Data.Range.purs @@ -0,0 +1,94 @@ +module Data.Range where + +import Prelude + +import Data.Enum (class Enum, pred, succ) +import Data.Generic.Rep (class Generic) +import Data.Maybe (Maybe(..)) +import Data.Show.Generic (genericShow) + +data RangeOrExact a + = RangeNotExact (Range a) + | RangeExact a + +data Bound a + = BoundIncluding a + | BoundExcluding a + +derive instance Generic (Bound a) _ +derive instance Ord a => Ord (Bound a) +derive instance Eq a => Eq (Bound a) +instance Show a => Show (Bound a) where + show = genericShow + +boundModify :: forall a. (a -> a) -> Bound a -> Bound a +boundModify f (BoundIncluding a) = BoundIncluding $ f a +boundModify f (BoundExcluding a) = BoundExcluding $ f a + +boundBottomContains :: forall a. Ord a => Bound a -> a -> Boolean +boundBottomContains (BoundIncluding ba) a = a >= ba +boundBottomContains (BoundExcluding ba) a = a > ba + +boundTopContains :: forall a. Ord a => Bound a -> a -> Boolean +boundTopContains (BoundIncluding ba) a = a <= ba +boundTopContains (BoundExcluding ba) a = a < ba + +data Range a + = RangeAbove (Bound a) + | RangeBelow (Bound a) + | RangeBetween (Bound a) (Bound a) + +derive instance Generic (Range a) _ +derive instance Ord a => Ord (Range a) +derive instance Eq a => Eq (Range a) +instance Show a => Show (Range a) where + show = genericShow + +instance Semigroup (Range a) where + append (RangeAbove a) (RangeBelow b) = RangeBetween a b + append (RangeBelow a) (RangeAbove b) = RangeBetween a b + append a _ = a + +modifyLower :: forall a. (a -> a) -> Range a -> Range a +modifyLower _ r@(RangeAbove _) = r +modifyLower f (RangeBelow b) = RangeBelow (boundModify f b) +modifyLower f (RangeBetween b top') = RangeBetween (boundModify f b) top' + +modifyUpper :: forall a. (a -> a) -> Range a -> Range a +modifyUpper _ r@(RangeBelow _) = r +modifyUpper f (RangeAbove b) = RangeAbove (boundModify f b) +modifyUpper f (RangeBetween bot' b) = RangeBetween bot' (boundModify f b) + +incl :: forall a. a -> Bound a +incl = BoundIncluding + +excl :: forall a. a -> Bound a +excl = BoundExcluding + +above :: forall a. Bound a -> Range a +above = RangeAbove + +below :: forall a. Bound a -> Range a +below = RangeBelow + +between :: forall a. Bound a -> Bound a -> Range a +between = RangeBetween + +bottom :: forall a. Enum a => Range a -> Maybe a +bottom (RangeBetween (BoundIncluding a) _) = Just a +bottom (RangeBetween (BoundExcluding a) _) = succ a +bottom (RangeAbove (BoundIncluding a)) = Just a +bottom (RangeAbove (BoundExcluding a)) = succ a +bottom _ = Nothing + +top :: forall a. Enum a => Range a -> Maybe a +top (RangeBetween _ (BoundIncluding a)) = Just a +top (RangeBetween _ (BoundExcluding a)) = pred a +top (RangeBelow (BoundIncluding a)) = Just a +top (RangeBelow (BoundExcluding a)) = pred a +top _ = Nothing + +contains :: forall a. Ord a => Range a -> a -> Boolean +contains (RangeBetween bot' top') a = boundBottomContains bot' a && boundTopContains top' a +contains (RangeAbove bot') a = boundBottomContains bot' a +contains (RangeBelow top') a = boundTopContains top' a diff --git a/src/Main.purs b/src/Main.purs deleted file mode 100644 index ee561ac..0000000 --- a/src/Main.purs +++ /dev/null @@ -1,7 +0,0 @@ -module Main where - -import Prelude -import Effect (Effect) - -main :: Effect Unit -main = pure unit