module Shady.ITransform
(
ITransform(..), inverse, andInverse
, ITrans(..)
) where
import Data.Monoid (Monoid(..))
import Control.Applicative (liftA2)
import Shady.Misc
import Shady.Complex (Complex)
import Shady.Language.Exp
data ITransform a = ITransform { itForward :: Unop a
, itBackward :: Unop a }
instance Monoid (ITransform a) where
mempty = ITransform id id
ITransform oF oB `mappend` ITransform iF iB =
ITransform (oF.iF) (iB.oB)
inverse :: Unop (ITransform a)
inverse (ITransform forw back) = ITransform back forw
andInverse :: (c -> Unop a) -> (c -> c) -> c -> ITransform a
andInverse f inva = liftA2 ITransform f (f.inva)
infixr 1 *:
class ITrans w a | a -> w where
(*:) :: ITransform w -> Unop a
instance ITrans w (E a) where
(*:) = const id
instance ITrans (Complex s) (Complex s) where (*:) = itForward
instance (ITrans w a, ITrans w b) => ITrans w (a,b) where
ix *: (a,b) = (ix *: a, ix *: b)
instance (ITrans w a, ITrans w b, ITrans w c) => ITrans w (a,b,c) where
ix *: (a,b,c) = (ix *: a, ix *: b, ix *: c)
instance (ITrans w a, ITrans w b, ITrans w c, ITrans w d ) => ITrans w (a,b,c,d) where
ix *: (a,b,c,d) =
(ix *: a, ix *: b, ix *: c, ix *: d)
instance (ITrans w a, ITrans w b) => ITrans w (a -> b) where
ix *: f = (*:) ix . f . (*:) (inverse ix)