module Data.Data.Indexed
(gmapI
,gindex
,gappend)
where
import Control.Monad
import Control.Monad.State
import Control.Monad.Writer
import Data.Data
import Data.Data.Exists
import Data.Maybe
gmapI :: (Data a, Num i,MonadState i m)
=> (forall d. Data d => d -> i -> m ())
-> a
-> m a
gmapI f y = gmapM go y
where
go d =
do i <- get
let !i' = i + 1
put i'
f d i
return d
gindex :: (Eq i, Num i,Data a)
=> i
-> a
-> Maybe D
gindex j x =
listToMaybe (evalState (execWriterT (gmapI grab x)) 0)
where grab d i =
when (i == j)
(tell [D d])
gappend :: (Num i,Data a,Monoid m)
=> (forall d. Data d => d -> i -> m)
-> a
-> m
gappend f x =
evalState (execWriterT (gmapI (\d i -> tell (f d i)) x)) 0