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

{- |
   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           = (NTree b -> [NTree b]) -> LA (NTree b) (NTree b)
forall b c. (b -> [c]) -> LA b c
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 a b. (a -> b -> b) -> b -> [a] -> b
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) -> LA (NTree b) c
-> LA (NTree b) [NTree b]
-> LA (NTree b) [NTree b]
-> LA (NTree b) [NTree b]
forall b c d. LA b c -> LA b d -> LA b d -> LA b d
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 b c. LA b c -> LA b [c]
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 b c. LA b c
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 :: forall b. (b -> Maybe b) -> LA (NTree b) (NTree b)
fmapNTreeA b -> Maybe b
f            = (NTree b -> NTree b) -> LA (NTree b) (NTree b)
forall b c. (b -> c) -> LA b c
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 ------------------------------------------------------------