{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
--------------------------------------------------------------------
-- |
-- Module    : Text.XML.Expat.Cursor
--
-- This module ported from Text.XML.Light.Cursor
--
-- XML cursors for working XML content withing the context of
-- an XML document.  This implementation is based on the general
-- tree zipper written by Krasimir Angelov and Iavor S. Diatchki.
--
-- With the exception of 'modifyContentM', then M-suffixed functions are
-- for use with monadic node types, as used when dealing with chunked I\/O
-- with the /hexpat-iteratee/ package.  In the more common pure case, you
-- wouldn't need these *M functions.

module Text.XML.Expat.Cursor
  ( 
  -- * Types
    Cursor, CursorG(..), Path, PathG
  , Tag(..), getTag, fromTag

  -- * Conversions
  , fromTree
  , fromForest
  , toForest
  , toTree

  -- * Moving around
  , parent
  , root
  , getChild
  , getChildM
  , firstChild
  , firstChildM
  , lastChild
  , lastChildM
  , left
  , leftM
  , right
  , rightM
  , nextDF
  , nextDFM

  -- ** Searching
  , findChild
  , findLeft
  , findRight
  , findRec
  , findRecM

  -- * Node classification
  , isRoot
  , isFirst
  , isFirstM
  , isLast
  , isLastM
  , isLeaf
  , isChild
  , hasChildren
  , getNodeIndex

  -- * Updates
  , setContent
  , modifyContent
  , modifyContentList
  , modifyContentListM
  , modifyContentM

  -- ** Inserting content
  , insertLeft
  , insertRight
  , insertManyLeft
  , insertManyRight
  , insertFirstChild
  , insertLastChild
  , insertManyFirstChild
  , insertManyLastChild
  , insertGoLeft
  , insertGoRight

  -- ** Removing content
  , removeLeft
  , removeLeftM
  , removeRight
  , removeRightM
  , removeGoLeft
  , removeGoLeftM
  , removeGoRight
  , removeGoRightM
  , removeGoUp

  ) where

import Text.XML.Expat.Tree
import Control.Monad (mzero, mplus)
import Data.Maybe(isNothing)
import Data.Monoid
import Data.Functor.Identity
import Data.List.Class (List(..), ListItem(..), cons, foldlL, lengthL)

data Tag tag text = Tag { forall tag text. Tag tag text -> tag
tagName    :: tag
                        , forall tag text. Tag tag text -> Attributes tag text
tagAttribs :: Attributes tag text
                        } deriving (Int -> Tag tag text -> ShowS
[Tag tag text] -> ShowS
Tag tag text -> String
(Int -> Tag tag text -> ShowS)
-> (Tag tag text -> String)
-> ([Tag tag text] -> ShowS)
-> Show (Tag tag text)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall tag text.
(Show tag, Show text) =>
Int -> Tag tag text -> ShowS
forall tag text. (Show tag, Show text) => [Tag tag text] -> ShowS
forall tag text. (Show tag, Show text) => Tag tag text -> String
$cshowsPrec :: forall tag text.
(Show tag, Show text) =>
Int -> Tag tag text -> ShowS
showsPrec :: Int -> Tag tag text -> ShowS
$cshow :: forall tag text. (Show tag, Show text) => Tag tag text -> String
show :: Tag tag text -> String
$cshowList :: forall tag text. (Show tag, Show text) => [Tag tag text] -> ShowS
showList :: [Tag tag text] -> ShowS
Show)

{-
setTag :: Tag -> Element -> Element
setTag t e = fromTag t (elContent e)
-}

fromTag :: MkElementClass n c => Tag tag text -> c (n c tag text) -> n c tag text
fromTag :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
Tag tag text -> c (n c tag text) -> n c tag text
fromTag Tag tag text
t c (n c tag text)
cs = tag -> Attributes tag text -> c (n c tag text) -> n c tag text
forall tag text.
tag -> Attributes tag text -> c (n c tag text) -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
tag -> Attributes tag text -> c (n c tag text) -> n c tag text
mkElement (Tag tag text -> tag
forall tag text. Tag tag text -> tag
tagName Tag tag text
t) (Tag tag text -> Attributes tag text
forall tag text. Tag tag text -> Attributes tag text
tagAttribs Tag tag text
t) c (n c tag text)
cs

-- | Generalized path within an XML document.
type PathG n c tag text = [(c (n c tag text),Tag tag text,c (n c tag text))]

-- | A path specific to @Text.XML.Expat.Tree.Node@ trees.
type Path tag text = PathG NodeG [] tag text

-- | Generalized cursor: The position of a piece of content in an XML document.
-- @n@ is the Node type and @c@ is the list type, which would usually be [],
-- except when you're using chunked I\/O.
data CursorG n c tag text = Cur
  { forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> n c tag text
current :: n c tag text       -- ^ The currently selected content.
  , forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts   :: c (n c tag text)   -- ^ Siblings on the left, closest first.
  , forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
rights  :: c (n c tag text)   -- ^ Siblings on the right, closest first.
  , forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> PathG n c tag text
parents :: PathG n c tag text -- ^ The contexts of the parent elements of this location.
  }

instance (Show (n c tag text), Show (c (n c tag text)), Show tag, Show text)
                                           => Show (CursorG n c tag text) where
    show :: CursorG n c tag text -> String
show (Cur n c tag text
c c (n c tag text)
l c (n c tag text)
r PathG n c tag text
p) = String
"Cur { current="String -> ShowS
forall a. [a] -> [a] -> [a]
++n c tag text -> String
forall a. Show a => a -> String
show n c tag text
cString -> ShowS
forall a. [a] -> [a] -> [a]
++
                         String
", lefts="String -> ShowS
forall a. [a] -> [a] -> [a]
++c (n c tag text) -> String
forall a. Show a => a -> String
show c (n c tag text)
lString -> ShowS
forall a. [a] -> [a] -> [a]
++
                         String
", rights="String -> ShowS
forall a. [a] -> [a] -> [a]
++c (n c tag text) -> String
forall a. Show a => a -> String
show c (n c tag text)
rString -> ShowS
forall a. [a] -> [a] -> [a]
++
                         String
", parents="String -> ShowS
forall a. [a] -> [a] -> [a]
++PathG n c tag text -> String
forall a. Show a => a -> String
show PathG n c tag text
pString -> ShowS
forall a. [a] -> [a] -> [a]
++String
" }"

-- | A cursor specific to @Text.XML.Expat.Tree.Node@ trees.
type Cursor tag text = CursorG NodeG [] tag text

-- Moving around ---------------------------------------------------------------

-- | The parent of the given location.
parent :: MkElementClass n c => CursorG n c tag text -> Maybe (CursorG n c tag text)
parent :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> Maybe (CursorG n c tag text)
parent CursorG n c tag text
loc =
  case CursorG n c tag text -> PathG n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> PathG n c tag text
parents CursorG n c tag text
loc of
    (c (n c tag text)
pls,Tag tag text
v,c (n c tag text)
prs) : PathG n c tag text
ps -> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just
      Cur { current :: n c tag text
current = (Tag tag text -> c (n c tag text) -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
Tag tag text -> c (n c tag text) -> n c tag text
fromTag Tag tag text
v
                    (c (n c tag text)
-> n c tag text -> c (n c tag text) -> c (n c tag text)
forall (c :: * -> *) a. List c => c a -> a -> c a -> c a
combChildren (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n c tag text
loc) (CursorG n c tag text -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> n c tag text
current CursorG n c tag text
loc) (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
rights CursorG n c tag text
loc)))
          , lefts :: c (n c tag text)
lefts = c (n c tag text)
pls, rights :: c (n c tag text)
rights = c (n c tag text)
prs, parents :: PathG n c tag text
parents = PathG n c tag text
ps
          }
    [] -> Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing


-- | The top-most parent of the given location.
root :: MkElementClass n c => CursorG n c tag text -> CursorG n c tag text
root :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> CursorG n c tag text
root CursorG n c tag text
loc = CursorG n c tag text
-> (CursorG n c tag text -> CursorG n c tag text)
-> Maybe (CursorG n c tag text)
-> CursorG n c tag text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe CursorG n c tag text
loc CursorG n c tag text -> CursorG n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> CursorG n c tag text
root (CursorG n c tag text -> Maybe (CursorG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> Maybe (CursorG n c tag text)
parent CursorG n c tag text
loc)

-- | The left sibling of the given location - pure version.
left :: CursorG n [] tag text -> Maybe (CursorG n [] tag text)
left :: forall (n :: (* -> *) -> * -> * -> *) tag text.
CursorG n [] tag text -> Maybe (CursorG n [] tag text)
left CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text -> ItemM [] (Maybe (CursorG n [] tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
leftM CursorG n [] tag text
loc

-- | The left sibling of the given location - used for monadic node types.
leftM :: List c => CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
leftM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
leftM CursorG n c tag text
loc = do
  let l :: c (n c tag text)
l = CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n c tag text
loc
  ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList c (n c tag text)
l
  case ListItem c (n c tag text)
li of
    ListItem c (n c tag text)
Nil -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing
    Cons n c tag text
t c (n c tag text)
ts -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
loc { current = t, lefts = ts
                                   , rights = cons (current loc) (rights loc) }

-- | The right sibling of the given location - pure version.
right :: CursorG n [] tag text -> Maybe (CursorG n [] tag text)
right :: forall (n :: (* -> *) -> * -> * -> *) tag text.
CursorG n [] tag text -> Maybe (CursorG n [] tag text)
right CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text -> ItemM [] (Maybe (CursorG n [] tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
rightM CursorG n [] tag text
loc

-- | The right sibling of the given location - used for monadic node types.
rightM :: List c => CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
rightM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
rightM CursorG n c tag text
loc = do
  let r :: c (n c tag text)
r = CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
rights CursorG n c tag text
loc
  ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList c (n c tag text)
r
  case ListItem c (n c tag text)
li of
    ListItem c (n c tag text)
Nil -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing
    Cons n c tag text
t c (n c tag text)
ts -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
loc { current = t, lefts = cons (current loc) (lefts loc)
                                   , rights = ts }

-- | The first child of the given location - pure version.
firstChild :: (NodeClass n [], Monoid tag) => CursorG n [] tag text -> Maybe (CursorG n [] tag text)
firstChild :: forall (n :: (* -> *) -> * -> * -> *) tag text.
(NodeClass n [], Monoid tag) =>
CursorG n [] tag text -> Maybe (CursorG n [] tag text)
firstChild CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text -> ItemM [] (Maybe (CursorG n [] tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
firstChildM CursorG n [] tag text
loc

-- | The first child of the given location - used for monadic node types.
firstChildM :: (NodeClass n c, Monoid tag) => CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
firstChildM :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
firstChildM CursorG n c tag text
loc = do
    case CursorG n c tag text
-> Maybe (c (n c tag text), PathG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text
-> Maybe (c (n c tag text), PathG n c tag text)
downParents CursorG n c tag text
loc of
        Just (c (n c tag text)
l, PathG n c tag text
ps) -> do
            ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList c (n c tag text)
l
            Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ case ListItem c (n c tag text)
li of
                Cons n c tag text
t c (n c tag text)
ts -> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just (CursorG n c tag text -> Maybe (CursorG n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a b. (a -> b) -> a -> b
$ Cur { current :: n c tag text
current = n c tag text
t, lefts :: c (n c tag text)
lefts = c (n c tag text)
forall a. c a
forall (m :: * -> *) a. MonadPlus m => m a
mzero, rights :: c (n c tag text)
rights = c (n c tag text)
ts , parents :: PathG n c tag text
parents = PathG n c tag text
ps }
                ListItem c (n c tag text)
Nil       -> Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing
        Maybe (c (n c tag text), PathG n c tag text)
Nothing -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | The last child of the given location - pure version.
lastChild :: (NodeClass n [], Monoid tag) => CursorG n [] tag text -> Maybe (CursorG n [] tag text)
lastChild :: forall (n :: (* -> *) -> * -> * -> *) tag text.
(NodeClass n [], Monoid tag) =>
CursorG n [] tag text -> Maybe (CursorG n [] tag text)
lastChild CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text -> ItemM [] (Maybe (CursorG n [] tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
lastChildM CursorG n [] tag text
loc

-- | The last child of the given location - used for monadic node types.
lastChildM :: (NodeClass n c, Monoid tag) => CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
lastChildM :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
lastChildM CursorG n c tag text
loc = do
    case CursorG n c tag text
-> Maybe (c (n c tag text), PathG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text
-> Maybe (c (n c tag text), PathG n c tag text)
downParents CursorG n c tag text
loc of
        Just (c (n c tag text)
l, PathG n c tag text
ps) -> do
            ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList (c (n c tag text) -> c (n c tag text)
forall (c :: * -> *) a. List c => c a -> c a
reverseL c (n c tag text)
l)
            Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ case ListItem c (n c tag text)
li of
                Cons n c tag text
t c (n c tag text)
ts -> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just (CursorG n c tag text -> Maybe (CursorG n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a b. (a -> b) -> a -> b
$ Cur { current :: n c tag text
current = n c tag text
t, lefts :: c (n c tag text)
lefts = c (n c tag text)
ts, rights :: c (n c tag text)
rights = c (n c tag text)
forall a. c a
forall (m :: * -> *) a. MonadPlus m => m a
mzero , parents :: PathG n c tag text
parents = PathG n c tag text
ps }
                ListItem c (n c tag text)
Nil       -> Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing
        Maybe (c (n c tag text), PathG n c tag text)
Nothing -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | Find the next left sibling that satisfies a predicate.
findLeft :: NodeClass n [] =>
            (CursorG n [] tag text -> Bool)
         -> CursorG n [] tag text
         -> Maybe (CursorG n [] tag text)
findLeft :: forall (n :: (* -> *) -> * -> * -> *) tag text.
NodeClass n [] =>
(CursorG n [] tag text -> Bool)
-> CursorG n [] tag text -> Maybe (CursorG n [] tag text)
findLeft CursorG n [] tag text -> Bool
p CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity ((CursorG n [] tag text -> Bool)
-> CursorG n [] tag text
-> ItemM [] (Maybe (CursorG n [] tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findLeftM CursorG n [] tag text -> Bool
p CursorG n [] tag text
loc)

-- | Find the next left sibling that satisfies a predicate.
findLeftM :: NodeClass n c =>
             (CursorG n c tag text -> Bool)
          -> CursorG n c tag text
          -> ItemM c (Maybe (CursorG n c tag text))
findLeftM :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findLeftM CursorG n c tag text -> Bool
p CursorG n c tag text
loc = do
    Maybe (CursorG n c tag text)
mLoc1 <- CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
leftM CursorG n c tag text
loc
    case Maybe (CursorG n c tag text)
mLoc1 of
        Just CursorG n c tag text
loc1 -> if CursorG n c tag text -> Bool
p CursorG n c tag text
loc1 then Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
loc1) else (CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findLeftM CursorG n c tag text -> Bool
p CursorG n c tag text
loc1
        Maybe (CursorG n c tag text)
Nothing   -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | Find the next right sibling that satisfies a predicate - pure version.
findRight :: (CursorG n [] tag text -> Bool)
          -> CursorG n [] tag text
          -> Maybe (CursorG n [] tag text)
findRight :: forall (n :: (* -> *) -> * -> * -> *) tag text.
(CursorG n [] tag text -> Bool)
-> CursorG n [] tag text -> Maybe (CursorG n [] tag text)
findRight CursorG n [] tag text -> Bool
p CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ (CursorG n [] tag text -> Bool)
-> CursorG n [] tag text
-> ItemM [] (Maybe (CursorG n [] tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
(CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findRightM CursorG n [] tag text -> Bool
p CursorG n [] tag text
loc

-- | Find the next right sibling that satisfies a predicate - used for monadic node types.
findRightM :: List c =>
              (CursorG n c tag text -> Bool)
           -> CursorG n c tag text
           -> ItemM c (Maybe (CursorG n c tag text))
findRightM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
(CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findRightM CursorG n c tag text -> Bool
p CursorG n c tag text
loc = do
    Maybe (CursorG n c tag text)
mLoc1 <- CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
rightM CursorG n c tag text
loc
    case Maybe (CursorG n c tag text)
mLoc1 of
        Just CursorG n c tag text
loc1 -> if CursorG n c tag text -> Bool
p CursorG n c tag text
loc1 then Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
loc1 else (CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
(CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findRightM CursorG n c tag text -> Bool
p CursorG n c tag text
loc1
        Maybe (CursorG n c tag text)
Nothing   -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | The first child that satisfies a predicate - pure version.
findChild :: (NodeClass n [], Monoid tag) =>
             (CursorG n [] tag text -> Bool)
          -> CursorG n [] tag text
          -> Maybe (CursorG n [] tag text)
findChild :: forall (n :: (* -> *) -> * -> * -> *) tag text.
(NodeClass n [], Monoid tag) =>
(CursorG n [] tag text -> Bool)
-> CursorG n [] tag text -> Maybe (CursorG n [] tag text)
findChild CursorG n [] tag text -> Bool
p CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ (CursorG n [] tag text -> Bool)
-> CursorG n [] tag text
-> ItemM [] (Maybe (CursorG n [] tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
(CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findChildM CursorG n [] tag text -> Bool
p CursorG n [] tag text
loc

-- | The first child that satisfies a predicate - used for monadic node types.
findChildM :: (NodeClass n c, Monoid tag) =>
              (CursorG n c tag text -> Bool)
           -> CursorG n c tag text
           -> ItemM c (Maybe (CursorG n c tag text))
findChildM :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
(CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findChildM CursorG n c tag text -> Bool
p CursorG n c tag text
loc = do
    Maybe (CursorG n c tag text)
mLoc1 <- CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
firstChildM CursorG n c tag text
loc
    case Maybe (CursorG n c tag text)
mLoc1 of
        Just CursorG n c tag text
loc1 -> if CursorG n c tag text -> Bool
p CursorG n c tag text
loc1 then Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
loc1 else (CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
(CursorG n c tag text -> Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findRightM CursorG n c tag text -> Bool
p CursorG n c tag text
loc1
        Maybe (CursorG n c tag text)
Nothing   -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | The next position in a left-to-right depth-first traversal of a document:
-- either the first child, right sibling, or the right sibling of a parent that
-- has one. Pure version.
nextDF :: (MkElementClass n [], Monoid tag) => CursorG n [] tag text -> Maybe (CursorG n [] tag text)
nextDF :: forall (n :: (* -> *) -> * -> * -> *) tag text.
(MkElementClass n [], Monoid tag) =>
CursorG n [] tag text -> Maybe (CursorG n [] tag text)
nextDF CursorG n [] tag text
c = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text -> ItemM [] (Maybe (CursorG n [] tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(MkElementClass n c, Monoid tag) =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
nextDFM CursorG n [] tag text
c

-- | The next position in a left-to-right depth-first traversal of a document:
-- either the first child, right sibling, or the right sibling of a parent that
-- has one. Used for monadic node types.
nextDFM :: (MkElementClass n c, Monoid tag) => CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
nextDFM :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(MkElementClass n c, Monoid tag) =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
nextDFM CursorG n c tag text
c = do
    Maybe (CursorG n c tag text)
mFirst <- CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
firstChildM CursorG n c tag text
c
    case Maybe (CursorG n c tag text)
mFirst of
        Just CursorG n c tag text
c' -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
c'
        Maybe (CursorG n c tag text)
Nothing -> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall {c :: * -> *} {n :: (* -> *) -> * -> * -> *} {tag} {text}.
MkElementClass n c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
up CursorG n c tag text
c
  where
    up :: CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
up CursorG n c tag text
x = do
        Maybe (CursorG n c tag text)
mRight <- CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
rightM CursorG n c tag text
x
        case Maybe (CursorG n c tag text)
mRight of
            Just CursorG n c tag text
c' -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
c'
            Maybe (CursorG n c tag text)
Nothing ->
                case CursorG n c tag text -> Maybe (CursorG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> Maybe (CursorG n c tag text)
parent CursorG n c tag text
x of
                    Just CursorG n c tag text
p -> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
up CursorG n c tag text
p
                    Maybe (CursorG n c tag text)
Nothing -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | Perform a depth first search for a descendant that satisfies the
-- given predicate. Pure version.
findRec :: (MkElementClass n [], Monoid tag) =>
           (CursorG n [] tag text -> Bool)
        -> CursorG n [] tag text
        -> Maybe (CursorG n [] tag text)
findRec :: forall (n :: (* -> *) -> * -> * -> *) tag text.
(MkElementClass n [], Monoid tag) =>
(CursorG n [] tag text -> Bool)
-> CursorG n [] tag text -> Maybe (CursorG n [] tag text)
findRec CursorG n [] tag text -> Bool
p CursorG n [] tag text
c = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ (CursorG n [] tag text -> ItemM [] Bool)
-> CursorG n [] tag text
-> ItemM [] (Maybe (CursorG n [] tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(MkElementClass n c, Monoid tag) =>
(CursorG n c tag text -> ItemM c Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findRecM (Bool -> Identity Bool
forall a. a -> Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Identity Bool)
-> (CursorG n [] tag text -> Bool)
-> CursorG n [] tag text
-> Identity Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CursorG n [] tag text -> Bool
p) CursorG n [] tag text
c

-- | Perform a depth first search for a descendant that satisfies the
-- given predicate. Used for monadic node types.
findRecM :: (MkElementClass n c, Monoid tag) =>
            (CursorG n c tag text -> ItemM c Bool)
         -> CursorG n c tag text
         -> ItemM c (Maybe (CursorG n c tag text))
findRecM :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(MkElementClass n c, Monoid tag) =>
(CursorG n c tag text -> ItemM c Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findRecM CursorG n c tag text -> ItemM c Bool
p CursorG n c tag text
c = do
    Bool
found <- CursorG n c tag text -> ItemM c Bool
p CursorG n c tag text
c
    if Bool
found
        then Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
c
        else do
            Maybe (CursorG n c tag text)
mC' <- CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(MkElementClass n c, Monoid tag) =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
nextDFM CursorG n c tag text
c
            case Maybe (CursorG n c tag text)
mC' of
                Just CursorG n c tag text
c' -> (CursorG n c tag text -> ItemM c Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(MkElementClass n c, Monoid tag) =>
(CursorG n c tag text -> ItemM c Bool)
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
findRecM CursorG n c tag text -> ItemM c Bool
p CursorG n c tag text
c'
                Maybe (CursorG n c tag text)
Nothing -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | The child with the given index (starting from 0). - pure version.
getChild :: (NodeClass n [], Monoid tag) => Int -> CursorG n [] tag text -> Maybe (CursorG n [] tag text)
getChild :: forall (n :: (* -> *) -> * -> * -> *) tag text.
(NodeClass n [], Monoid tag) =>
Int -> CursorG n [] tag text -> Maybe (CursorG n [] tag text)
getChild Int
n CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ Int
-> CursorG n [] tag text
-> ItemM [] (Maybe (CursorG n [] tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
Int
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
getChildM Int
n CursorG n [] tag text
loc

-- | The child with the given index (starting from 0) - used for monadic node types.
getChildM :: (NodeClass n c, Monoid tag) =>
             Int
          -> CursorG n c tag text
          -> ItemM c (Maybe (CursorG n c tag text))
getChildM :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
Int
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
getChildM Int
n CursorG n c tag text
loc = do
    let mParents :: Maybe (c (n c tag text), PathG n c tag text)
mParents = CursorG n c tag text
-> Maybe (c (n c tag text), PathG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text
-> Maybe (c (n c tag text), PathG n c tag text)
downParents CursorG n c tag text
loc
    case Maybe (c (n c tag text), PathG n c tag text)
mParents of
        Just (c (n c tag text)
ts, PathG n c tag text
ps) -> do
            Maybe (c (n c tag text), n c tag text, c (n c tag text))
mSplit <- c (n c tag text)
-> Int
-> ItemM
     c (Maybe (c (n c tag text), n c tag text, c (n c tag text)))
forall (c :: * -> *) a.
List c =>
c a -> Int -> ItemM c (Maybe (c a, a, c a))
splitChildrenM c (n c tag text)
ts Int
n
            case Maybe (c (n c tag text), n c tag text, c (n c tag text))
mSplit of
                Just (c (n c tag text)
ls,n c tag text
t,c (n c tag text)
rs) -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just (CursorG n c tag text -> Maybe (CursorG n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a b. (a -> b) -> a -> b
$
                    Cur { current :: n c tag text
current = n c tag text
t, lefts :: c (n c tag text)
lefts = c (n c tag text)
ls, rights :: c (n c tag text)
rights = c (n c tag text)
rs, parents :: PathG n c tag text
parents = PathG n c tag text
ps }
                Maybe (c (n c tag text), n c tag text, c (n c tag text))
Nothing -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing
        Maybe (c (n c tag text), PathG n c tag text)
Nothing -> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing


-- | private: computes the parent for "down" operations.
downParents :: (NodeClass n c, Monoid tag) => CursorG n c tag text -> Maybe (c (n c tag text), PathG n c tag text)
downParents :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text
-> Maybe (c (n c tag text), PathG n c tag text)
downParents CursorG n c tag text
loc =
  case CursorG n c tag text -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> n c tag text
current CursorG n c tag text
loc of
    n c tag text
e | n c tag text -> Bool
forall tag text. n c tag text -> Bool
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
n c tag text -> Bool
isElement n c tag text
e ->
        let n :: tag
n = n c tag text -> tag
forall tag text. Monoid tag => n c tag text -> tag
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
n c tag text -> tag
getName n c tag text
e
            a :: [(tag, text)]
a = n c tag text -> [(tag, text)]
forall tag text. n c tag text -> [(tag, text)]
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
n c tag text -> [(tag, text)]
getAttributes n c tag text
e
            c :: c (n c tag text)
c = n c tag text -> c (n c tag text)
forall tag text. n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
n c tag text -> c (n c tag text)
getChildren n c tag text
e
        in  (c (n c tag text), PathG n c tag text)
-> Maybe (c (n c tag text), PathG n c tag text)
forall a. a -> Maybe a
Just ( c (n c tag text)
c
                      , (c (n c tag text), Tag tag text, c (n c tag text))
-> PathG n c tag text -> PathG n c tag text
forall a. a -> [a] -> [a]
forall (l :: * -> *) a. List l => a -> l a -> l a
cons (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n c tag text
loc, tag -> [(tag, text)] -> Tag tag text
forall tag text. tag -> Attributes tag text -> Tag tag text
Tag tag
n [(tag, text)]
a, CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
rights CursorG n c tag text
loc) (CursorG n c tag text -> PathG n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> PathG n c tag text
parents CursorG n c tag text
loc)
                      )
    n c tag text
_      -> Maybe (c (n c tag text), PathG n c tag text)
forall a. Maybe a
Nothing

getTag :: Node tag text -> Tag tag text
getTag :: forall tag text. Node tag text -> Tag tag text
getTag Node tag text
e = Tag { tagName :: tag
tagName = Node tag text -> tag
forall (c :: * -> *) tag text. NodeG c tag text -> tag
eName Node tag text
e
               , tagAttribs :: Attributes tag text
tagAttribs = Node tag text -> Attributes tag text
forall (c :: * -> *) tag text. NodeG c tag text -> [(tag, text)]
eAttributes Node tag text
e
               }


-- Conversions -----------------------------------------------------------------

-- | A cursor for the given content.
fromTree :: List c => n c tag text -> CursorG n c tag text
fromTree :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
n c tag text -> CursorG n c tag text
fromTree n c tag text
t = Cur { current :: n c tag text
current = n c tag text
t, lefts :: c (n c tag text)
lefts = c (n c tag text)
forall a. c a
forall (m :: * -> *) a. MonadPlus m => m a
mzero, rights :: c (n c tag text)
rights = c (n c tag text)
forall a. c a
forall (m :: * -> *) a. MonadPlus m => m a
mzero, parents :: PathG n c tag text
parents = [] }

-- | The location of the first tree in a forest - pure version.
fromForest :: NodeClass n [] => [n [] tag text] -> Maybe (CursorG n [] tag text)
fromForest :: forall (n :: (* -> *) -> * -> * -> *) tag text.
NodeClass n [] =>
[n [] tag text] -> Maybe (CursorG n [] tag text)
fromForest [n [] tag text]
l = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ [n [] tag text] -> ItemM [] (Maybe (CursorG n [] tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
c (n c tag text) -> ItemM c (Maybe (CursorG n c tag text))
fromForestM [n [] tag text]
l

-- | The location of the first tree in a forest - used with monadic node types.
fromForestM :: List c => c (n c tag text) -> ItemM c (Maybe (CursorG n c tag text))
fromForestM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
c (n c tag text) -> ItemM c (Maybe (CursorG n c tag text))
fromForestM c (n c tag text)
l = do
    ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList c (n c tag text)
l
    Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ case ListItem c (n c tag text)
li of
        Cons n c tag text
t c (n c tag text)
ts -> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just Cur { current :: n c tag text
current = n c tag text
t, lefts :: c (n c tag text)
lefts = c (n c tag text)
forall a. c a
forall (m :: * -> *) a. MonadPlus m => m a
mzero, rights :: c (n c tag text)
rights = c (n c tag text)
ts
                                                          , parents :: PathG n c tag text
parents = [] }
        ListItem c (n c tag text)
Nil       -> Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | Computes the tree containing this location.
toTree :: MkElementClass n c => CursorG n c tag text -> n c tag text
toTree :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> n c tag text
toTree CursorG n c tag text
loc = CursorG n c tag text -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> n c tag text
current (CursorG n c tag text -> CursorG n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> CursorG n c tag text
root CursorG n c tag text
loc)

-- | Computes the forest containing this location.
toForest :: MkElementClass n c => CursorG n c tag text -> c (n c tag text)
toForest :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> c (n c tag text)
toForest CursorG n c tag text
loc = let r :: CursorG n c tag text
r = CursorG n c tag text -> CursorG n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> CursorG n c tag text
root CursorG n c tag text
loc in c (n c tag text)
-> n c tag text -> c (n c tag text) -> c (n c tag text)
forall (c :: * -> *) a. List c => c a -> a -> c a -> c a
combChildren (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n c tag text
r) (CursorG n c tag text -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> n c tag text
current CursorG n c tag text
r) (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
rights CursorG n c tag text
r)


-- Queries ---------------------------------------------------------------------

-- | Are we at the top of the document?
isRoot :: CursorG n c tag text -> Bool
isRoot :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> Bool
isRoot CursorG n c tag text
loc = [(c (n c tag text), Tag tag text, c (n c tag text))] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (CursorG n c tag text
-> [(c (n c tag text), Tag tag text, c (n c tag text))]
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> PathG n c tag text
parents CursorG n c tag text
loc)

-- | Are we at the left end of the the document? (Pure version.)
isFirst :: CursorG n [] tag text -> Bool
isFirst :: forall (n :: (* -> *) -> * -> * -> *) tag text.
CursorG n [] tag text -> Bool
isFirst CursorG n [] tag text
loc = Identity Bool -> Bool
forall a. Identity a -> a
runIdentity (Identity Bool -> Bool) -> Identity Bool -> Bool
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text -> ItemM [] Bool
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c Bool
isFirstM CursorG n [] tag text
loc

-- | Are we at the left end of the the document? (Used for monadic node types.)
isFirstM :: List c => CursorG n c tag text -> ItemM c Bool
isFirstM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c Bool
isFirstM CursorG n c tag text
loc = do
    ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n c tag text
loc)
    Bool -> ItemM c Bool
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> ItemM c Bool) -> Bool -> ItemM c Bool
forall a b. (a -> b) -> a -> b
$ case ListItem c (n c tag text)
li of
        ListItem c (n c tag text)
Nil -> Bool
True
        ListItem c (n c tag text)
_   -> Bool
False

-- | Are we at the right end of the document? (Pure version.)
isLast :: CursorG n [] tag text -> Bool
isLast :: forall (n :: (* -> *) -> * -> * -> *) tag text.
CursorG n [] tag text -> Bool
isLast CursorG n [] tag text
loc = Identity Bool -> Bool
forall a. Identity a -> a
runIdentity (Identity Bool -> Bool) -> Identity Bool -> Bool
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text -> ItemM [] Bool
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c Bool
isLastM CursorG n [] tag text
loc

-- | Are we at the right end of the document? (Used for monadic node types.)
isLastM :: List c => CursorG n c tag text -> ItemM c Bool
isLastM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c Bool
isLastM CursorG n c tag text
loc = do
    ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
rights CursorG n c tag text
loc)
    Bool -> ItemM c Bool
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> ItemM c Bool) -> Bool -> ItemM c Bool
forall a b. (a -> b) -> a -> b
$ case ListItem c (n c tag text)
li of
        ListItem c (n c tag text)
Nil -> Bool
True
        ListItem c (n c tag text)
_   -> Bool
False

-- | Are we at the bottom of the document?
isLeaf :: (NodeClass n c, Monoid tag) => CursorG n c tag text -> Bool
isLeaf :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text -> Bool
isLeaf CursorG n c tag text
loc = Maybe (c (n c tag text), PathG n c tag text) -> Bool
forall a. Maybe a -> Bool
isNothing (CursorG n c tag text
-> Maybe (c (n c tag text), PathG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text
-> Maybe (c (n c tag text), PathG n c tag text)
downParents CursorG n c tag text
loc)

-- | Do we have a parent?
isChild :: CursorG n c tag text -> Bool
isChild :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> Bool
isChild CursorG n c tag text
loc = Bool -> Bool
not (CursorG n c tag text -> Bool
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> Bool
isRoot CursorG n c tag text
loc)

-- | Get the node index inside the sequence of children - pure version.
getNodeIndex :: CursorG n [] tag text -> Int
getNodeIndex :: forall (n :: (* -> *) -> * -> * -> *) tag text.
CursorG n [] tag text -> Int
getNodeIndex CursorG n [] tag text
loc = Identity Int -> Int
forall a. Identity a -> a
runIdentity (Identity Int -> Int) -> Identity Int -> Int
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text -> ItemM [] Int
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c Int
getNodeIndexM CursorG n [] tag text
loc

-- | Get the node index inside the sequence of children - used for monadic node types.
getNodeIndexM :: List c => CursorG n c tag text -> ItemM c Int
getNodeIndexM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c Int
getNodeIndexM CursorG n c tag text
loc = c (n c tag text) -> ItemM c Int
forall i (l :: * -> *) a. (Integral i, List l) => l a -> ItemM l i
lengthL (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n c tag text
loc)

-- | Do we have children?
hasChildren :: (NodeClass n c, Monoid tag) => CursorG n c tag text -> Bool
hasChildren :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text -> Bool
hasChildren CursorG n c tag text
loc = Bool -> Bool
not (CursorG n c tag text -> Bool
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(NodeClass n c, Monoid tag) =>
CursorG n c tag text -> Bool
isLeaf CursorG n c tag text
loc)



-- Updates ---------------------------------------------------------------------

-- | Change the current content.
setContent :: n c tag text -> CursorG n c tag text -> CursorG n c tag text
setContent :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
n c tag text -> CursorG n c tag text -> CursorG n c tag text
setContent n c tag text
t CursorG n c tag text
loc = CursorG n c tag text
loc { current = t }

-- | Modify the current content.
modifyContent :: (n c tag text -> n c tag text) -> CursorG n c tag text -> CursorG n c tag text
modifyContent :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
(n c tag text -> n c tag text)
-> CursorG n c tag text -> CursorG n c tag text
modifyContent n c tag text -> n c tag text
f CursorG n c tag text
loc = n c tag text -> CursorG n c tag text -> CursorG n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
n c tag text -> CursorG n c tag text -> CursorG n c tag text
setContent (n c tag text -> n c tag text
f (CursorG n c tag text -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> n c tag text
current CursorG n c tag text
loc)) CursorG n c tag text
loc

-- | Modify the current content - pure version.
modifyContentList :: NodeClass n [] =>
                     (n [] tag text -> [n [] tag text]) -> CursorG n [] tag text -> Maybe (CursorG n [] tag text)
modifyContentList :: forall (n :: (* -> *) -> * -> * -> *) tag text.
NodeClass n [] =>
(n [] tag text -> [n [] tag text])
-> CursorG n [] tag text -> Maybe (CursorG n [] tag text)
modifyContentList n [] tag text -> [n [] tag text]
f CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ (n [] tag text -> [n [] tag text])
-> CursorG n [] tag text
-> ItemM [] (Maybe (CursorG n [] tag text))
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(n c tag text -> c (n c tag text))
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
modifyContentListM n [] tag text -> [n [] tag text]
f CursorG n [] tag text
loc

-- | Modify the current content - used for monadic node types.
modifyContentListM :: NodeClass n c =>
                      (n c tag text -> c (n c tag text))
                   -> CursorG n c tag text
                   -> ItemM c (Maybe (CursorG n c tag text))
modifyContentListM :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(n c tag text -> c (n c tag text))
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
modifyContentListM n c tag text -> c (n c tag text)
f CursorG n c tag text
loc = CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
removeGoRightM (CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text)))
-> CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ c (n c tag text) -> CursorG n c tag text -> CursorG n c tag text
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
c (n c tag text) -> CursorG n c tag text -> CursorG n c tag text
insertManyRight (n c tag text -> c (n c tag text)
f (n c tag text -> c (n c tag text))
-> n c tag text -> c (n c tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> n c tag text
current CursorG n c tag text
loc) CursorG n c tag text
loc

-- | Modify the current content, allowing for an effect.
modifyContentM :: Monad m => (n [] tag text -> m (n [] tag text)) -> CursorG n [] tag text -> m (CursorG n [] tag text)
modifyContentM :: forall (m :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
Monad m =>
(n [] tag text -> m (n [] tag text))
-> CursorG n [] tag text -> m (CursorG n [] tag text)
modifyContentM n [] tag text -> m (n [] tag text)
f CursorG n [] tag text
loc = do n [] tag text
x <- n [] tag text -> m (n [] tag text)
f (CursorG n [] tag text -> n [] tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> n c tag text
current CursorG n [] tag text
loc)
                          CursorG n [] tag text -> m (CursorG n [] tag text)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (n [] tag text -> CursorG n [] tag text -> CursorG n [] tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
n c tag text -> CursorG n c tag text -> CursorG n c tag text
setContent n [] tag text
x CursorG n [] tag text
loc)

-- | Insert content to the left of the current position.
insertLeft :: List c => n c tag text -> CursorG n c tag text -> CursorG n c tag text
insertLeft :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
n c tag text -> CursorG n c tag text -> CursorG n c tag text
insertLeft n c tag text
t CursorG n c tag text
loc = CursorG n c tag text
loc { lefts = t `cons` lefts loc }

-- | Insert content to the right of the current position.
insertRight :: List c => n c tag text -> CursorG n c tag text -> CursorG n c tag text
insertRight :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
n c tag text -> CursorG n c tag text -> CursorG n c tag text
insertRight n c tag text
t CursorG n c tag text
loc = CursorG n c tag text
loc { rights = t `cons` rights loc }

-- | Insert content to the left of the current position.
insertManyLeft :: List c => c (n c tag text) -> CursorG n c tag text -> CursorG n c tag text
insertManyLeft :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
c (n c tag text) -> CursorG n c tag text -> CursorG n c tag text
insertManyLeft c (n c tag text)
t CursorG n c tag text
loc = CursorG n c tag text
loc { lefts = reverseL t `mplus` lefts loc }

-- | Insert content to the right of the current position.
insertManyRight :: List c => c (n c tag text) -> CursorG n c tag text -> CursorG n c tag text
insertManyRight :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
c (n c tag text) -> CursorG n c tag text -> CursorG n c tag text
insertManyRight c (n c tag text)
t CursorG n c tag text
loc = CursorG n c tag text
loc { rights = t `mplus` rights loc }

-- | Insert content as the first child of the current position.
mapChildren :: NodeClass n c => (c (n c tag text) -> c (n c tag text))
            -> CursorG n c tag text
            -> Maybe (CursorG n c tag text)
mapChildren :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(c (n c tag text) -> c (n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
mapChildren c (n c tag text) -> c (n c tag text)
f CursorG n c tag text
loc = let e :: n c tag text
e = CursorG n c tag text -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> n c tag text
current CursorG n c tag text
loc in
  if n c tag text -> Bool
forall tag text. n c tag text -> Bool
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
n c tag text -> Bool
isElement n c tag text
e then
      CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just (CursorG n c tag text -> Maybe (CursorG n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n c tag text
loc { current = modifyChildren f e }
  else
      Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | Insert content as the first child of the current position.
insertFirstChild :: NodeClass n c => n c tag text -> CursorG n c tag text -> Maybe (CursorG n c tag text)
insertFirstChild :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
n c tag text
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
insertFirstChild n c tag text
t = (c (n c tag text) -> c (n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(c (n c tag text) -> c (n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
mapChildren (n c tag text
t n c tag text -> c (n c tag text) -> c (n c tag text)
forall a. a -> c a -> c a
forall (l :: * -> *) a. List l => a -> l a -> l a
`cons`)

-- | Insert content as the first child of the current position.
insertLastChild :: NodeClass n c => n c tag text -> CursorG n c tag text -> Maybe (CursorG n c tag text)
insertLastChild :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
n c tag text
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
insertLastChild n c tag text
t = (c (n c tag text) -> c (n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(c (n c tag text) -> c (n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
mapChildren (c (n c tag text) -> c (n c tag text) -> c (n c tag text)
forall a. c a -> c a -> c a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` n c tag text -> c (n c tag text)
forall a. a -> c a
forall (m :: * -> *) a. Monad m => a -> m a
return n c tag text
t)

-- | Insert content as the first child of the current position.
insertManyFirstChild :: NodeClass n c => c (n c tag text) -> CursorG n c tag text -> Maybe (CursorG n c tag text)
insertManyFirstChild :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
c (n c tag text)
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
insertManyFirstChild c (n c tag text)
t = (c (n c tag text) -> c (n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(c (n c tag text) -> c (n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
mapChildren (c (n c tag text)
t c (n c tag text) -> c (n c tag text) -> c (n c tag text)
forall a. c a -> c a -> c a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus`)

-- | Insert content as the first child of the current position.
insertManyLastChild :: NodeClass n c => c (n c tag text) -> CursorG n c tag text -> Maybe (CursorG n c tag text)
insertManyLastChild :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
c (n c tag text)
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
insertManyLastChild c (n c tag text)
t = (c (n c tag text) -> c (n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
NodeClass n c =>
(c (n c tag text) -> c (n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
mapChildren (c (n c tag text) -> c (n c tag text) -> c (n c tag text)
forall a. c a -> c a -> c a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` c (n c tag text)
t)

-- | Remove the content on the left of the current position, if any - pure version.
removeLeft :: CursorG n [] tag text -> Maybe (n [] tag text, CursorG n [] tag text)
removeLeft :: forall (n :: (* -> *) -> * -> * -> *) tag text.
CursorG n [] tag text
-> Maybe (n [] tag text, CursorG n [] tag text)
removeLeft CursorG n [] tag text
loc = Identity (Maybe (n [] tag text, CursorG n [] tag text))
-> Maybe (n [] tag text, CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (n [] tag text, CursorG n [] tag text))
 -> Maybe (n [] tag text, CursorG n [] tag text))
-> Identity (Maybe (n [] tag text, CursorG n [] tag text))
-> Maybe (n [] tag text, CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text
-> ItemM [] (Maybe (n [] tag text, CursorG n [] tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text
-> ItemM c (Maybe (n c tag text, CursorG n c tag text))
removeLeftM CursorG n [] tag text
loc

-- | Remove the content on the left of the current position, if any - used for monadic node types.
removeLeftM :: List c => CursorG n c tag text -> ItemM c (Maybe (n c tag text, CursorG n c tag text))
removeLeftM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text
-> ItemM c (Maybe (n c tag text, CursorG n c tag text))
removeLeftM CursorG n c tag text
loc = do
    ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n c tag text
loc)
    Maybe (n c tag text, CursorG n c tag text)
-> ItemM c (Maybe (n c tag text, CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (n c tag text, CursorG n c tag text)
 -> ItemM c (Maybe (n c tag text, CursorG n c tag text)))
-> Maybe (n c tag text, CursorG n c tag text)
-> ItemM c (Maybe (n c tag text, CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ case ListItem c (n c tag text)
li of
       Cons n c tag text
l c (n c tag text)
ls -> (n c tag text, CursorG n c tag text)
-> Maybe (n c tag text, CursorG n c tag text)
forall a. a -> Maybe a
Just ((n c tag text, CursorG n c tag text)
 -> Maybe (n c tag text, CursorG n c tag text))
-> (n c tag text, CursorG n c tag text)
-> Maybe (n c tag text, CursorG n c tag text)
forall a b. (a -> b) -> a -> b
$ (n c tag text
l,CursorG n c tag text
loc { lefts = ls })
       ListItem c (n c tag text)
Nil       -> Maybe (n c tag text, CursorG n c tag text)
forall a. Maybe a
Nothing

-- | Remove the content on the right of the current position, if any - pure version.
removeRight :: CursorG n [] tag text -> Maybe (n [] tag text, CursorG n [] tag text)
removeRight :: forall (n :: (* -> *) -> * -> * -> *) tag text.
CursorG n [] tag text
-> Maybe (n [] tag text, CursorG n [] tag text)
removeRight CursorG n [] tag text
loc = Identity (Maybe (n [] tag text, CursorG n [] tag text))
-> Maybe (n [] tag text, CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (n [] tag text, CursorG n [] tag text))
 -> Maybe (n [] tag text, CursorG n [] tag text))
-> Identity (Maybe (n [] tag text, CursorG n [] tag text))
-> Maybe (n [] tag text, CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text
-> ItemM [] (Maybe (n [] tag text, CursorG n [] tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text
-> ItemM c (Maybe (n c tag text, CursorG n c tag text))
removeRightM CursorG n [] tag text
loc

-- | Remove the content on the left of the current position, if any - used for monadic node types.
removeRightM :: List c => CursorG n c tag text -> ItemM c (Maybe (n c tag text, CursorG n c tag text))
removeRightM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text
-> ItemM c (Maybe (n c tag text, CursorG n c tag text))
removeRightM CursorG n c tag text
loc = do
    ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
rights CursorG n c tag text
loc)
    Maybe (n c tag text, CursorG n c tag text)
-> ItemM c (Maybe (n c tag text, CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (n c tag text, CursorG n c tag text)
 -> ItemM c (Maybe (n c tag text, CursorG n c tag text)))
-> Maybe (n c tag text, CursorG n c tag text)
-> ItemM c (Maybe (n c tag text, CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ case ListItem c (n c tag text)
li of
       Cons n c tag text
l c (n c tag text)
ls -> (n c tag text, CursorG n c tag text)
-> Maybe (n c tag text, CursorG n c tag text)
forall a. a -> Maybe a
Just ((n c tag text, CursorG n c tag text)
 -> Maybe (n c tag text, CursorG n c tag text))
-> (n c tag text, CursorG n c tag text)
-> Maybe (n c tag text, CursorG n c tag text)
forall a b. (a -> b) -> a -> b
$ (n c tag text
l,CursorG n c tag text
loc { rights = ls })
       ListItem c (n c tag text)
Nil       -> Maybe (n c tag text, CursorG n c tag text)
forall a. Maybe a
Nothing

-- | Insert content to the left of the current position.
-- The new content becomes the current position.
insertGoLeft :: List c => n c tag text -> CursorG n c tag text -> CursorG n c tag text
insertGoLeft :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
n c tag text -> CursorG n c tag text -> CursorG n c tag text
insertGoLeft n c tag text
t CursorG n c tag text
loc = CursorG n c tag text
loc { current = t, rights = current loc `cons` rights loc }

-- | Insert content to the right of the current position.
-- The new content becomes the current position.
insertGoRight :: List c => n c tag text -> CursorG n c tag text -> CursorG n c tag text
insertGoRight :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
n c tag text -> CursorG n c tag text -> CursorG n c tag text
insertGoRight n c tag text
t CursorG n c tag text
loc = CursorG n c tag text
loc { current = t, lefts = current loc `cons` lefts loc }

-- | Remove the current element.
-- The new position is the one on the left. Pure version.
removeGoLeft :: CursorG n [] tag text -> Maybe (CursorG n [] tag text)
removeGoLeft :: forall (n :: (* -> *) -> * -> * -> *) tag text.
CursorG n [] tag text -> Maybe (CursorG n [] tag text)
removeGoLeft CursorG n [] tag text
loc = case CursorG n [] tag text -> [n [] tag text]
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n [] tag text
loc of
                     n [] tag text
l : [n [] tag text]
ls -> CursorG n [] tag text -> Maybe (CursorG n [] tag text)
forall a. a -> Maybe a
Just CursorG n [] tag text
loc { current = l, lefts = ls }
                     []     -> Maybe (CursorG n [] tag text)
forall a. Maybe a
Nothing

-- | Remove the current element.
-- The new position is the one on the left. Pure version.
removeGoLeftM :: List c => CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
removeGoLeftM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
removeGoLeftM CursorG n c tag text
loc = do
    ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n c tag text
loc)
    Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ case ListItem c (n c tag text)
li of
        Cons n c tag text
l c (n c tag text)
ls -> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
loc { current = l, lefts = ls }
        ListItem c (n c tag text)
Nil       -> Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | Remove the current element.
-- The new position is the one on the right. Pure version.
removeGoRight :: CursorG n [] tag text -> Maybe (CursorG n [] tag text)
removeGoRight :: forall (n :: (* -> *) -> * -> * -> *) tag text.
CursorG n [] tag text -> Maybe (CursorG n [] tag text)
removeGoRight CursorG n [] tag text
loc = Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a. Identity a -> a
runIdentity (Identity (Maybe (CursorG n [] tag text))
 -> Maybe (CursorG n [] tag text))
-> Identity (Maybe (CursorG n [] tag text))
-> Maybe (CursorG n [] tag text)
forall a b. (a -> b) -> a -> b
$ CursorG n [] tag text -> ItemM [] (Maybe (CursorG n [] tag text))
forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
removeGoRightM CursorG n [] tag text
loc

-- | Remove the current element.
-- The new position is the one on the right. Used for monadic node types.
removeGoRightM :: List c => CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
removeGoRightM :: forall (c :: * -> *) (n :: (* -> *) -> * -> * -> *) tag text.
List c =>
CursorG n c tag text -> ItemM c (Maybe (CursorG n c tag text))
removeGoRightM CursorG n c tag text
loc = do
     ListItem c (n c tag text)
li <- c (n c tag text) -> ItemM c (ListItem c (n c tag text))
forall a. c a -> ItemM c (ListItem c a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
rights CursorG n c tag text
loc)
     Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (CursorG n c tag text)
 -> ItemM c (Maybe (CursorG n c tag text)))
-> Maybe (CursorG n c tag text)
-> ItemM c (Maybe (CursorG n c tag text))
forall a b. (a -> b) -> a -> b
$ case ListItem c (n c tag text)
li of
         Cons n c tag text
l c (n c tag text)
ls -> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just CursorG n c tag text
loc { current = l, rights = ls }
         ListItem c (n c tag text)
Nil       -> Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing

-- | Remove the current element.
-- The new position is the parent of the old position.
removeGoUp :: MkElementClass n c => CursorG n c tag text -> Maybe (CursorG n c tag text)
removeGoUp :: forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
CursorG n c tag text -> Maybe (CursorG n c tag text)
removeGoUp CursorG n c tag text
loc =
    case (CursorG n c tag text -> PathG n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> PathG n c tag text
parents CursorG n c tag text
loc) of
        [] -> Maybe (CursorG n c tag text)
forall a. Maybe a
Nothing
        (c (n c tag text)
pls, Tag tag text
v, c (n c tag text)
prs):PathG n c tag text
ps -> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a. a -> Maybe a
Just (CursorG n c tag text -> Maybe (CursorG n c tag text))
-> CursorG n c tag text -> Maybe (CursorG n c tag text)
forall a b. (a -> b) -> a -> b
$
            Cur { current :: n c tag text
current = Tag tag text -> c (n c tag text) -> n c tag text
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
MkElementClass n c =>
Tag tag text -> c (n c tag text) -> n c tag text
fromTag Tag tag text
v (c (n c tag text) -> c (n c tag text)
forall (c :: * -> *) a. List c => c a -> c a
reverseL (CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
lefts CursorG n c tag text
loc) c (n c tag text) -> c (n c tag text) -> c (n c tag text)
forall a. c a -> c a -> c a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` CursorG n c tag text -> c (n c tag text)
forall (n :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
CursorG n c tag text -> c (n c tag text)
rights CursorG n c tag text
loc)
                , lefts :: c (n c tag text)
lefts = c (n c tag text)
pls, rights :: c (n c tag text)
rights = c (n c tag text)
prs, parents :: PathG n c tag text
parents = PathG n c tag text
ps
                }


-- | private: Gets the given element of a list.
-- Also returns the preceding elements (reversed) and the following elements.
splitChildrenM :: List c => c a -> Int -> ItemM c (Maybe (c a,a,c a))
splitChildrenM :: forall (c :: * -> *) a.
List c =>
c a -> Int -> ItemM c (Maybe (c a, a, c a))
splitChildrenM c a
_ Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Maybe (c a, a, c a) -> ItemM c (Maybe (c a, a, c a))
forall a. a -> ItemM c a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (c a, a, c a)
forall a. Maybe a
Nothing
splitChildrenM c a
cs Int
pos = c a -> c a -> Int -> ItemM c (Maybe (c a, a, c a))
forall {a} {l :: * -> *} {l :: * -> *} {a}.
(Eq a, Num a, List l, List l) =>
l a -> l a -> a -> ItemM l (Maybe (l a, a, l a))
loop c a
forall a. c a
forall (m :: * -> *) a. MonadPlus m => m a
mzero c a
cs Int
pos
  where
    loop :: l a -> l a -> a -> ItemM l (Maybe (l a, a, l a))
loop l a
acc l a
l a
n = do
        ListItem l a
li <- l a -> ItemM l (ListItem l a)
forall a. l a -> ItemM l (ListItem l a)
forall (l :: * -> *) a. List l => l a -> ItemM l (ListItem l a)
runList l a
l
        case ListItem l a
li of
            ListItem l a
Nil -> Maybe (l a, a, l a) -> ItemM l (Maybe (l a, a, l a))
forall a. a -> ItemM l a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (l a, a, l a)
forall a. Maybe a
Nothing
            Cons a
x l a
l' -> if a
n a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0
                then Maybe (l a, a, l a) -> ItemM l (Maybe (l a, a, l a))
forall a. a -> ItemM l a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (l a, a, l a) -> ItemM l (Maybe (l a, a, l a)))
-> Maybe (l a, a, l a) -> ItemM l (Maybe (l a, a, l a))
forall a b. (a -> b) -> a -> b
$ (l a, a, l a) -> Maybe (l a, a, l a)
forall a. a -> Maybe a
Just (l a
acc, a
x, l a
l')
                else l a -> l a -> a -> ItemM l (Maybe (l a, a, l a))
loop (a -> l a -> l a
forall a. a -> l a -> l a
forall (l :: * -> *) a. List l => a -> l a -> l a
cons a
x l a
acc) l a
l' (a -> ItemM l (Maybe (l a, a, l a)))
-> a -> ItemM l (Maybe (l a, a, l a))
forall a b. (a -> b) -> a -> b
$! a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1

-- | private: combChildren ls x ys = reverse ls ++ [x] ++ rs
combChildren :: List c =>
                c a    -- ^ ls
             -> a      -- ^ x
             -> c a    -- ^ rs
             -> c a
combChildren :: forall (c :: * -> *) a. List c => c a -> a -> c a -> c a
combChildren c a
ls a
t c a
rs = ItemM c (c a) -> c a
forall a. ItemM c (c a) -> c a
forall (l :: * -> *) a. List l => ItemM l (l a) -> l a
joinL (ItemM c (c a) -> c a) -> ItemM c (c a) -> c a
forall a b. (a -> b) -> a -> b
$ (c a -> a -> c a) -> c a -> c a -> ItemM c (c a)
forall (l :: * -> *) a b.
List l =>
(a -> b -> a) -> a -> l b -> ItemM l a
foldlL ((a -> c a -> c a) -> c a -> a -> c a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> c a -> c a
forall a. a -> c a -> c a
forall (l :: * -> *) a. List l => a -> l a -> l a
cons) (a -> c a -> c a
forall a. a -> c a -> c a
forall (l :: * -> *) a. List l => a -> l a -> l a
cons a
t c a
rs) c a
ls

reverseL :: List c => c a -> c a
reverseL :: forall (c :: * -> *) a. List c => c a -> c a
reverseL = ItemM c (c a) -> c a
forall a. ItemM c (c a) -> c a
forall (l :: * -> *) a. List l => ItemM l (l a) -> l a
joinL (ItemM c (c a) -> c a) -> (c a -> ItemM c (c a)) -> c a -> c a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c a -> a -> c a) -> c a -> c a -> ItemM c (c a)
forall (l :: * -> *) a b.
List l =>
(a -> b -> a) -> a -> l b -> ItemM l a
foldlL ((a -> c a -> c a) -> c a -> a -> c a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> c a -> c a
forall a. a -> c a -> c a
forall (l :: * -> *) a. List l => a -> l a -> l a
cons) c a
forall a. c a
forall (m :: * -> *) a. MonadPlus m => m a
mzero