packages feed

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