-- ------------------------------------------------------------

{- |
   Module     : Control.Arrow.NTreeEdit
   Copyright  : Copyright (C) 2011 Uwe Schmidt
   License    : MIT

   Maintainer : Uwe Schmidt (uwe\@fh-wedel.de)
   Stability  : experimental
   Portability: portable

   arrows for efficient editing of rose trees

-}

-- ------------------------------------------------------------

module Control.Arrow.NTreeEdit
where

import Control.Arrow
import Control.Arrow.ArrowIf
import Control.Arrow.ArrowList
import Control.Arrow.ListArrow

import Data.Maybe
import Data.Tree.NTree.TypeDefs
import Data.Tree.NTree.Edit

-- ------------------------------------------------------------

-- | Edit parts of a rose tree
--
-- The subtrees to be modified are selected by the first part of the IfThen pairs
-- The modification by the second part

editNTreeA              :: [IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))] ->
                           LA (NTree b) (NTree b)
editNTreeA :: forall b c.
[IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
-> LA (NTree b) (NTree b)
editNTreeA [IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
cs           = forall (a :: * -> * -> *) b c. ArrowList a => (b -> [c]) -> a b c
arrL forall a b. (a -> b) -> a -> b
$ forall a. (NTree a -> Maybe [NTree a]) -> NTree a -> [NTree a]
editNTreeBottomUp NTree b -> Maybe [NTree b]
ef
    where
    ef :: NTree b -> Maybe [NTree b]
ef                  = forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a b. LA a b -> a -> [b]
runLA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\ (LA (NTree b) c
g :-> LA (NTree b) (NTree b)
h) -> forall (a :: * -> * -> *) b c d.
ArrowIf a =>
a b c -> a b d -> a b d -> a b d
ifA LA (NTree b) c
g (forall (a :: * -> * -> *) b c. ArrowList a => a b c -> a b [c]
listA LA (NTree b) (NTree b)
h)) forall (a :: * -> * -> *) b c. ArrowList a => a b c
none forall a b. (a -> b) -> a -> b
$ [IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
cs)

fmapNTreeA              :: (b -> Maybe b) -> LA (NTree b) (NTree b)
fmapNTreeA :: forall b. (b -> Maybe b) -> LA (NTree b) (NTree b)
fmapNTreeA b -> Maybe b
f            = forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr forall a b. (a -> b) -> a -> b
$ forall a. (a -> Maybe a) -> NTree a -> NTree a
mapNTree' b -> Maybe b
f

-- eof ------------------------------------------------------------