packages feed

Hs2lib-0.4.8: WinDll/Utils/Types.hs

-----------------------------------------------------------------------------
-- |
-- Module      :  Windll
-- Copyright   :  (c) Tamar Christina 2009 - 2010
-- License     :  BSD3
-- 
-- Maintainer  :  tamar@zhox.com
-- Stability   :  experimental
-- Portability :  portable
--
-- General Util functions for the Haskell-Src-Exts datatypes
--
-----------------------------------------------------------------------------
module WinDll.Utils.Types where

import Language.Haskell.Exts

import Data.Generics (everywhere, mkT, everything, mkQ)

import WinDll.Structs.Folds.HaskellSrcExts

class Simplify a where
    simplify :: a -> a
  
instance Simplify a => Simplify [a] where
    simplify = map simplify
  
instance Simplify Type where
    simplify = simplifyParenthesis
-- | This function strips all unneeded parenthesis and keeps
--   only the bare minimum or parenthesis in types. We do this
--   to normalize the types and makes them easier to compare.
simplifyParenthesis :: Type -> Type
simplifyParenthesis = addParen . stripParen

-- | This function strips all parenthesis from a type.
stripParen :: Type -> Type
stripParen = everywhere (mkT isParen)
  where isParen :: Type -> Type
        isParen (TyParen a) = a
        isParen x           = x
        
-- | Adds the bare minimum of parenthesis to a type. This
--   requires that 'stripParen' was called first.
addParen :: Type -> Type
addParen = everywhere (mkT mkFun)
  where mkFun :: Type -> Type
        mkFun (TyFun a b) = if hasFun a
                               then TyFun (TyParen a) b
                               else TyFun a b
        mkFun (TyApp a b) = if hasFun b || hasApp b
                               then TyApp a (TyParen b)
                               else TyApp a b
        mkFun x           = x
        
-- | Checks to see if a type contains a function application (->)
hasFun :: Type -> Bool
hasFun = everything (||) (False `mkQ` isFun)
  where isFun :: Type -> Bool
        isFun (TyFun{}) = True
        isFun _         = False
        
-- | Checks to see if a type contains a type application (a b)
hasApp :: Type -> Bool
hasApp = everything (||) (False `mkQ` isApp)
  where isApp :: Type -> Bool
        isApp (TyApp{}) = True
        isApp _         = False