{-# LANGUAGE Safe #-} -- | Internally the range library converts your ranges into an internal representation of -- multiple ranges that I call a RangeMerge. When you do multiple unions and intersections -- in a row converting to and from that data structure becomes extra work that is not -- required. To amortize those costs away the RangeTree structure exists. You can specify -- a tree of operations in advance and then evaluate them all at once. This is not only -- useful for efficiency but for parsing too. Use RangeTree's whenever you wish to perform -- multiple operations in a row and wish for it to be as efficient as possible. module Data.Range.RangeTree ( evaluate , RangeTree(..) , RangeOperation(..) ) where import Data.Range.Data import qualified Data.Range.Algebra as Alg toExpr :: RangeTree a -> Alg.RangeExpr [Range a] toExpr (RangeLeaf a) = Alg.const a toExpr (RangeNodeInvert a) = Alg.invert (toExpr a) toExpr (RangeNode RangeUnion a b) = Alg.union (toExpr a) (toExpr b) toExpr (RangeNode RangeIntersection a b) = Alg.intersection (toExpr a) (toExpr b) toExpr (RangeNode RangeDifference a b) = Alg.difference (toExpr a) (toExpr b) -- | Evaluates a Range Tree into the final set of ranges that it compresses down to. Use -- this whenever you want to finally evaluate your constructed Range Tree. evaluate :: (Ord a, Enum a) => RangeTree a -> [Range a] evaluate = Alg.eval . toExpr