r-tree-1.0.0.0: no/No/Tree/D2.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
Reference spatial tree implemented using a naive list of elements.
Every fold/map is \(O (n)\).
-}
module No.Tree.D2 where
import Data.R2Tree.Double.Unsafe (MBR (..), Predicate (..))
import Control.DeepSeq
import qualified Data.Foldable as Fold
import qualified Data.List as List
import Prelude hiding (Foldable (..))
newtype NoTree a = NoTree { toList :: [(MBR, a)] }
instance Show a => Show (NoTree a) where
show = showString "fromList " . flip showList "" . toList
instance NFData a => NFData (NoTree a) where
rnf = liftRnf (\(ba, a) -> ba `seq` rnf a) . toList
instance Functor NoTree where
fmap f = NoTree . fmap (fmap f) . toList
instance Fold.Foldable NoTree where
foldMap f = Fold.foldMap (f . snd) . toList
foldr f z = Fold.foldr (f . snd) z . toList
foldr' f z = Fold.foldr' (f . snd) z . toList
foldl f z = Fold.foldl (\acc -> f acc . snd) z . toList
foldl' f z = Fold.foldl' (\acc -> f acc . snd) z . toList
instance Traversable NoTree where
traverse f = fmap NoTree . Prelude.traverse (Prelude.traverse f) . toList
empty :: NoTree a
empty = NoTree []
singleton :: MBR -> a -> NoTree a
singleton bx x = NoTree [(bx, x)]
null :: NoTree a -> Bool
null = List.null . toList
length :: NoTree a -> Int
length = List.length . toList
insert :: MBR -> a -> NoTree a -> NoTree a
insert ba a = NoTree . (:) (ba, a) . toList
delete :: MBR -> NoTree a -> NoTree a
delete ba no = let (xs, ys) = break ((== ba) . fst) $ toList no
in NoTree $ xs <> drop 1 ys
mapWithKey :: (MBR -> a -> b) -> NoTree a -> NoTree b
mapWithKey f = NoTree . fmap (\ ~(ba, a) -> (ba, f ba a) ) . toList
adjustRangeWithKey :: Predicate -> (MBR -> a -> a) -> NoTree a -> NoTree a
adjustRangeWithKey (Predicate _ checkLeaf) f =
NoTree . fmap (\(ba, a) -> (ba, opt ba a)) . toList
where
opt ba a | checkLeaf ba = f ba a
| otherwise = a
foldMapRangeWithKey :: Monoid m => Predicate -> (MBR -> a -> m) -> NoTree a -> m
foldMapRangeWithKey (Predicate _ checkLeaf) f = Fold.foldMap opt . toList
where
opt (ba, a) | checkLeaf ba = f ba a
| otherwise = mempty
foldrRangeWithKey :: Predicate -> (MBR -> a -> b -> b) -> b -> NoTree a -> b
foldrRangeWithKey (Predicate _ checkLeaf) f z = Fold.foldr opt z . toList
where
opt (ba, a) acc | checkLeaf ba = f ba a acc
| otherwise = acc
foldrRangeWithKey' :: Predicate -> (MBR -> a -> b -> b) -> b -> NoTree a -> b
foldrRangeWithKey' (Predicate _ checkLeaf) f z = Fold.foldr' opt z . toList
where
opt (ba, a) acc | checkLeaf ba = f ba a acc
| otherwise = acc
foldlRangeWithKey :: Predicate -> (b -> MBR -> a -> b) -> b -> NoTree a -> b
foldlRangeWithKey (Predicate _ checkLeaf) f z = Fold.foldl opt z . toList
where
opt acc (ba, a) | checkLeaf ba = f acc ba a
| otherwise = acc
foldlRangeWithKey' :: Predicate -> (b -> MBR -> a -> b) -> b -> NoTree a -> b
foldlRangeWithKey' (Predicate _ checkLeaf) f z = Fold.foldl' opt z . toList
where
opt acc (ba, a) | checkLeaf ba = f acc ba a
| otherwise = acc
traverseWithKey
:: Applicative f => (MBR -> a -> f b) -> NoTree a -> f (NoTree b)
traverseWithKey f =
fmap NoTree . Prelude.traverse ( \(ba, a) -> (,) ba <$> f ba a) . toList
traverseRangeWithKey
:: Applicative f
=> Predicate -> (MBR -> a -> f a) -> NoTree a -> f (NoTree a)
traverseRangeWithKey (Predicate _ checkLeaf) f =
fmap NoTree . Prelude.traverse ( \(ba, a) -> (,) ba <$> opt ba a) . toList
where
opt ba a | checkLeaf ba = f ba a
| otherwise = pure a
fromList :: [(MBR, a)] -> NoTree a
fromList = NoTree