module Text.XML.Basic.Utility where

import Data.List.HT (switchL, break, )
import Data.Tuple.HT (mapSnd, )


import Prelude hiding (break, )


{- |
Needs 'break' from utility-ht in order to be as lazy as 'updateAppend''.
-}
updateAppend :: (a -> Bool) -> a -> (a -> a) -> [a] -> [a]
updateAppend :: forall a. (a -> Bool) -> a -> (a -> a) -> [a] -> [a]
updateAppend a -> Bool
p a
deflt a -> a
f =
   forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. [a] -> [a] -> [a]
(++) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. b -> (a -> [a] -> b) -> [a] -> b
switchL (a
deflt,[]) ((,) forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f)) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall a. (a -> Bool) -> [a] -> ([a], [a])
break a -> Bool
p

{- |
Apply @f@ to the first element, where @p@ holds.
If no such element exists, append the default value @deflt@ to the list.
-}
updateAppend' :: (a -> Bool) -> a -> (a -> a) -> [a] -> [a]
updateAppend' :: forall a. (a -> Bool) -> a -> (a -> a) -> [a] -> [a]
updateAppend' a -> Bool
p a
deflt a -> a
f =
   let recourse :: [a] -> [a]
recourse [a]
xt =
          forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:) forall a b. (a -> b) -> a -> b
$
          case [a]
xt of
             [] -> (a
deflt,[])
             (a
x:[a]
xs) ->
                if a -> Bool
p a
x
                  then (a -> a
f a
x, [a]
xs)
                  else (a
x, [a] -> [a]
recourse [a]
xs)
   in  [a] -> [a]
recourse