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

    {- |
       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 :: [IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
    -> LA (NTree b) (NTree b)
    editNTreeA cs :: [IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
    cs           = (NTree b -> [NTree b]) -> LA (NTree b) (NTree b)
    forall (a :: * -> * -> *) b c. ArrowList a => (b -> [c]) -> a b c
    arrL ((NTree b -> [NTree b]) -> LA (NTree b) (NTree b))
    -> (NTree b -> [NTree b]) -> LA (NTree b) (NTree b)
    forall a b. (a -> b) -> a -> b
    $ (NTree b -> Maybe [NTree b]) -> NTree b -> [NTree 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                  = [[NTree b]] -> Maybe [NTree b]
    forall a. [a] -> Maybe a
    listToMaybe ([[NTree b]] -> Maybe [NTree b])
    -> (NTree b -> [[NTree b]]) -> NTree b -> Maybe [NTree b]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (LA (NTree b) [NTree b] -> NTree b -> [[NTree b]]
    forall a b. LA a b -> a -> [b]
    runLA (LA (NTree b) [NTree b] -> NTree b -> [[NTree b]])
    -> ([IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
        -> LA (NTree b) [NTree b])
    -> [IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
    -> NTree b
    -> [[NTree b]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))
     -> LA (NTree b) [NTree b] -> LA (NTree b) [NTree b])
    -> LA (NTree b) [NTree b]
    -> [IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
    -> LA (NTree b) [NTree b]
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\ (g :: LA (NTree b) c
    g :-> h :: LA (NTree b) (NTree b)
    h) -> LA (NTree b) c
    -> LA (NTree b) [NTree b]
    -> LA (NTree b) [NTree b]
    -> LA (NTree b) [NTree b]
    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 (LA (NTree b) (NTree b) -> LA (NTree b) [NTree b]
    forall (a :: * -> * -> *) b c. ArrowList a => a b c -> a b [c]
    listA LA (NTree b) (NTree b)
    h)) LA (NTree b) [NTree b]
    forall (a :: * -> * -> *) b c. ArrowList a => a b c
    none ([IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
     -> NTree b -> [[NTree b]])
    -> [IfThen (LA (NTree b) c) (LA (NTree b) (NTree b))]
    -> NTree b
    -> [[NTree b]]
    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 :: (b -> Maybe b) -> LA (NTree b) (NTree b)
    fmapNTreeA f :: b -> Maybe b
    f            = (NTree b -> NTree b) -> LA (NTree b) (NTree b)
    forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
    arr ((NTree b -> NTree b) -> LA (NTree b) (NTree b))
    -> (NTree b -> NTree b) -> LA (NTree b) (NTree b)
    forall a b. (a -> b) -> a -> b
    $ (b -> Maybe b) -> NTree b -> NTree b
    forall a. (a -> Maybe a) -> NTree a -> NTree a
    mapNTree' b -> Maybe b
    f

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