The operations should be largely self-explanatory:
data Transform {- abstract type -}
{- creators -}
combinedTr :: Translation -> Scaling -> Rotation -> Transform
generalTr :: Double -> Double -> Double -> Double -> Translation -> Transform
idTr :: Transform
transTr :: Translation -> Transform
scaleTr :: Scaling -> Transform
rotateTr :: Rotation -> Transform
{- setter functions -}
addTranslation :: Transform -> Translation -> Transform
setTranslation :: Transform -> Translation -> Transform
addScaling :: Transform -> Scaling -> Transform
setScaling :: Transform -> Scaling -> Transform
addRotation :: Transform -> Rotation -> Transform
setRotation :: Transform -> Rotation -> Transform
combineTransforms :: Transform -> Transform -> Transform
{- querying/getter functions -}
getScaling :: Transform -> Scaling
getRotation :: Transform -> Rotation
getTranslation :: Transform -> Translation
getUpperLeft :: Transform -> (Double,Double,Double,Double)
detTransform :: Transform -> Int
invertTransform :: Transform -> Transform
{- predicates -}
hasRotation :: Transform -> Bool (see comments)
isIdentity :: Transform -> Bool
isDetZero :: Transform -> Bool