{- |
    Module      :  $Header$
    Description :  TODO
    Copyright   :  (c)        2017 Finn Teegen
    License     :  BSD-3-clause

    Maintainer  :  bjp@informatik.uni-kiel.de
    Stability   :  experimental
    Portability :  portable

   TODO
-}

module IL.Typing (Typeable(..)) where

import Base.Messages (internalError)

import IL.Type

class Typeable a where
  typeOf :: a -> Type

instance Typeable ConstrTerm where
  typeOf :: ConstrTerm -> Type
typeOf (LiteralPattern ty :: Type
ty _) = Type
ty
  typeOf (ConstructorPattern ty :: Type
ty _ _) = Type
ty
  typeOf (VariablePattern ty :: Type
ty _) = Type
ty

instance Typeable Expression where
  typeOf :: Expression -> Type
typeOf (Literal ty :: Type
ty _) = Type
ty
  typeOf (Variable ty :: Type
ty _) = Type
ty
  typeOf (Function ty :: Type
ty _ _) = Type
ty
  typeOf (Constructor ty :: Type
ty _ _) = Type
ty
  typeOf (Apply e :: Expression
e _) = case Expression -> Type
forall a. Typeable a => a -> Type
typeOf Expression
e of
    TypeArrow _ ty :: Type
ty -> Type
ty
    _ -> String -> Type
forall a. String -> a
internalError "IL.Typing.typeOf: application"
  typeOf (Case _ _ as :: [Alt]
as) = Alt -> Type
forall a. Typeable a => a -> Type
typeOf (Alt -> Type) -> Alt -> Type
forall a b. (a -> b) -> a -> b
$ [Alt] -> Alt
forall a. [a] -> a
head [Alt]
as
  typeOf (Or e :: Expression
e _) = Expression -> Type
forall a. Typeable a => a -> Type
typeOf Expression
e
  typeOf (Exist _ _ e :: Expression
e) = Expression -> Type
forall a. Typeable a => a -> Type
typeOf Expression
e
  typeOf (Let _ e :: Expression
e) = Expression -> Type
forall a. Typeable a => a -> Type
typeOf Expression
e
  typeOf (Letrec _ e :: Expression
e) = Expression -> Type
forall a. Typeable a => a -> Type
typeOf Expression
e
  typeOf (Typed e :: Expression
e _) = Expression -> Type
forall a. Typeable a => a -> Type
typeOf Expression
e

instance Typeable Alt where
  typeOf :: Alt -> Type
typeOf (Alt _ e :: Expression
e) = Expression -> Type
forall a. Typeable a => a -> Type
typeOf Expression
e