{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, FunctionalDependencies #-}moduleCSPM.TypeChecker.CommonwhereimportCSPM.DataStructures.SyntaximportCSPM.DataStructures.TypesimportCSPM.TypeChecker.BuiltInFunctionsimportCSPM.TypeChecker.ExceptionsimportCSPM.TypeChecker.MonadimportCSPM.TypeChecker.UnificationimportUtil.PrettyPrint-- a -> b <=> We can't have two instances that match on a but differ on bclassTypeCheckableab|a->bwheretypeCheck::a->TypeCheckMonadbtypeChecka=caseerrorContextaofJustc->addErrorContextc(typeCheck'a)Nothing->typeCheck'atypeCheckExpect::a->Type->TypeCheckMonadbtypeCheckExpect__=panic"typeCheckExpect not supported"typeCheck'::a->TypeCheckMonadberrorContext::a->MaybeErrorContextinstanceTypeCheckableLiteralTypewhereerrorContexta=NothingtypeCheck'(Intn)=returnTInttypeCheck'(Boolb)=returnTBoolensureAreEqual::TypeCheckableaType=>[a]->TypeCheckMonadTypeensureAreEqual[]=freshTypeVarensureAreEqual(e:es)=dot<-typeCheckemapM(\e->typeCheckExpectet)esreturntensureIsList::TypeCheckableab=>a->TypeCheckMonadbensureIsListe=dofv<-freshTypeVartypeCheckExpecte(TSeqfv)ensureIsSet::TypeCheckableab=>a->TypeCheckMonadbensureIsSete=dofv<-freshTypeVarWithConstraints[Eq]typeCheckExpecte(TSetfv)ensureIsBool::TypeCheckableab=>a->TypeCheckMonadbensureIsBoole=typeCheckExpecteTBoolensureIsInt::TypeCheckableab=>a->TypeCheckMonadbensureIsInte=typeCheckExpecteTIntensureIsChannel::TypeCheckableab=>a->TypeCheckMonadbensureIsChannele=typeCheckExpecteTEventableensureIsEvent::TypeCheckableab=>a->TypeCheckMonadbensureIsEvente=typeCheckExpecteTEventensureIsProc::TypeCheckableab=>a->TypeCheckMonadbensureIsProce=typeCheckExpecteTProcensureHasConstraint::Constraint->Type->TypeCheckMonadTypeensureHasConstraintct=dofv1<-freshTypeVarWithConstraints[c]unifyfv1t