module Ideas.Common.Rule.Parameter
(
input, inputWith
, transInput1, transInput2, transInput3, transInputWith
, readRef2, readRef3
, output, outputWith
, outputOnly, outputOnly2, outputOnly3, outputOnlyWith
, writeRef2, writeRef3, writeRef2_, writeRef3_
, ParamTrans
, parameter1, parameter2, parameter3
, transRef
, supplyParameters
) where
import Control.Arrow
import Data.Maybe
import Ideas.Common.Context
import Ideas.Common.Environment
import Ideas.Common.Rule.Transformation
import Ideas.Common.View
input :: Ref i -> Trans (i, a) b -> Trans a b
input = inputWith . readRef
inputWith :: Trans a i -> Trans (i, a) b -> Trans a b
inputWith f g = (f &&& identity) >>> g
transInput1 :: Ref i -> (i -> a -> Maybe b) -> Trans a b
transInput1 = transInputWith . readRef
transInput2 :: Ref i1 -> Ref i2 -> (i1 -> i2 -> a -> Maybe b) -> Trans a b
transInput2 r1 r2 = transInputWith (readRef2 r1 r2) . uncurry
transInput3 :: Ref i1 -> Ref i2 -> Ref i3 -> (i1 -> i2 -> i3 -> a -> Maybe b) -> Trans a b
transInput3 r1 r2 r3 = transInputWith (readRef3 r1 r2 r3) . uncurry3
transInputWith :: MakeTrans f => Trans a i -> (i -> a -> f b) -> Trans a b
transInputWith t = inputWith t . makeTrans . uncurry
readRef2 :: Ref a -> Ref b -> Trans x (a, b)
readRef2 r1 r2 = readRef r1 &&& readRef r2
readRef3 :: Ref a -> Ref b -> Ref c -> Trans x (a, b, c)
readRef3 r1 r2 r3 = readRef r1 &&& readRef2 r2 r3 >>^ to3
output :: Ref o -> Trans a (b, o) -> Trans a b
output = outputWith . writeRef
outputWith :: Trans o x -> Trans a (b, o) -> Trans a b
outputWith f g = g >>> second f >>^ fst
outputOnly :: Ref o -> Trans a o -> Trans a a
outputOnly = outputOnlyWith . writeRef
outputOnly2 :: Ref o1 -> Ref o2 -> Trans a (o1, o2) -> Trans a a
outputOnly2 r1 = outputOnlyWith . writeRef2 r1
outputOnly3 :: Ref o1 -> Ref o2 -> Ref o3 -> Trans a (o1, o2, o3) -> Trans a a
outputOnly3 r1 r2 = outputOnlyWith . writeRef3 r1 r2
outputOnlyWith :: Trans o x -> Trans a o -> Trans a a
outputOnlyWith f g = ((g >>> f) &&& identity) >>^ snd
writeRef2 :: Ref a -> Ref b -> Trans (a, b) (a, b)
writeRef2 r1 r2 = writeRef r1 *** writeRef r2
writeRef2_ :: Ref a -> Ref b -> Trans (a, b) ()
writeRef2_ r1 r2 = writeRef2 r1 r2 >>^ const ()
writeRef3 :: Ref a -> Ref b -> Ref c -> Trans (a, b, c) (a, b, c)
writeRef3 r1 r2 r3 = from3 ^>> writeRef r1 *** writeRef2 r2 r3 >>^ to3
writeRef3_ :: Ref a -> Ref b -> Ref c -> Trans (a, b, c) ()
writeRef3_ r1 r2 r3 = writeRef3 r1 r2 r3 >>^ const ()
type ParamTrans i a = Trans (i, a) a
parameter1 :: Ref a -> (a -> b -> Maybe b) -> ParamTrans a b
parameter1 r1 f = first (transRef r1) >>> makeTrans (uncurry f)
parameter2 :: Ref a -> Ref b -> (a -> b -> c -> Maybe c) -> ParamTrans (a, b) c
parameter2 r1 r2 f = first (transRef r1 *** transRef r2) >>> makeTrans (uncurry (uncurry f))
parameter3 :: Ref a -> Ref b -> Ref c -> (a -> b -> c -> d -> Maybe d) -> ParamTrans (a, b, c) d
parameter3 r1 r2 r3 f = first (from3 ^>> t >>^ to3) >>> makeTrans (uncurry (\(a, b, c) -> f a b c))
where
t = transRef r1 *** (transRef r2 *** transRef r3)
transRef :: Ref a -> Trans a a
transRef r = (identity &&& readRefMaybe r) >>> uncurry fromMaybe ^>> writeRef r
supplyParameters :: ParamTrans b a -> Trans a b -> Transformation (Context a)
supplyParameters f g = transLiftContextIn $
transUseEnvironment (g &&& identity) >>> first f
from3 :: (a, b, c) -> (a, (b, c))
from3 (a, b, c) = (a, (b, c))
to3 :: (a, (b, c)) -> (a, b, c)
to3 (a, (b, c)) = (a, b, c)
uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 f (a, b, c) = f a b c