packages feed

KiCS-debugger-0.1.0: biosphere/src/Curry/Module/TransformationMonad.lcurry

Monad for Flat/Abstract Curry Transformation
============================================

This module defines a monad for Flat/Abstract Curry transformation, especially
for transforming expressions, because the monad state holds information about
the expression depth and breadth.

Required imports for an abstract monadic expression transformation:

> import Maybe
> import SrcRef

Bind operators
--------------

> infixl 1 >>=.
> infixl 2 >>.

Monad
-----

Monad state contains the index of the next fresh variable and maybe an info
tree (plus a flag if the next `ignoreSrcRef` should be performed, see further
info about this flag below at `ignoreSrcRef`):

> type TMState = (Int,Maybe (InfoTree,Bool))
> type TM a = TMState -> (TMState,a)

`return` of the transform monad:

> ret :: a -> TM a
> ret x td = (td,x)

`bind` of the transform monad:

> (>>=.) :: TM a -> (a -> TM b) -> TM b
> (f >>=. g) td = case f td of
>                      (td',x) -> g x td'
>
> (>>.) :: TM a -> TM b -> TM b
> f >>. g = f >>=. \_ -> g

Runs the monad with the given index of a fresh variable and no info tree.

> runVar :: Int -> TM a -> a
> runVar var m = snd (m (var,Nothing))

Runs the monad with and an initial state of fresh var 0 and no info tree.

> run :: TM a -> a
> run = runVar 0


Actions
-------

Extracts the monad state.

> state :: TM TMState
> state tms = (tms,tms)

Returns a fresh variable.

> freshVar :: TM Int
> freshVar (var,mInfoTree) = ((var+1,mInfoTree),var)

Returns `n` fresh variables.

> freshVars :: Int -> TM [Int]
> freshVars n (var,mInfoTree) = ((var+n,mInfoTree),(take n (from var)))
>   where from i = i:(from $ i+1)

Set the current info tree.

> setInfoTree :: InfoTree -> TM ()
> setInfoTree infoTree (var,_) = ((var,Just (infoTree,True)),())

Returns the current info tree.

> currentInfoTree :: TM InfoTree
> currentInfoTree state@(_,Just (infoTree,_)) = (state,infoTree)

Extracts the current source reference and sets the info tree to the next static
info (flag is set to `True`, the regular state).

> nextSrcRefs :: TM [SrcRef]
> nextSrcRefs (var,Just (infoTree,_)) =
>   let (srcRefs,nextInfoTree) = nextStaticInfo infoTree in
>     ((var,Just (nextInfoTree,True)),srcRefs)

Ingores (extracts it, but does not return) the next source reference (of a
variable). Does not extract (leave current info tree as it is) if the
`performFlag` is not set.
This is required to handle variable expressions which are arguments of flexible
`case` expressions, because they do not have a source reference as they are in
fact rule patterns.

> ignoreVarRefs :: TM ()
> ignoreVarRefs (var,Just (infoTree,performFlag)) =
>   let nextInfoTree = if performFlag
>                         then snd $ nextStaticInfo infoTree
>                         else infoTree in
>     ((var,Just (nextInfoTree,True)),())

Enables the `performFlag` according to `ignoreVarRefs`.

> skipNextVar :: TM ()
> skipNextVar (var,Just (infoTree,_)) = ((var,Just (infoTree,False)),())

Sequence for this monad, which includes increasing depth before and decreasing
after the sequence and increasing breadth before each sequenced action.

> sequence :: [TM a] -> TM [a]
> sequence = foldr mcons (ret [])
>   where mcons p q = p >>=. \x -> q >>=. \ys -> ret (x:ys)