Привет, я пишу интерпретатор C-подобного, статически типизированного языка в Haskell. Я хочу выполнить проверку типов перед выполнением кода, но у меня с этим проблемы. Прежде всего, ниже приведены некоторые определения типов из моего абстрактного синтаксиса:
newtype Ident = Ident String deriving (Eq,Ord,Show)
data Exp = {-- some other value constructors --} | EFuncWithParams Ident [Exp]
data Type = TInt | TDouble | {-- some other value constructors --} | TFunction [Exp]
type TCM a = ErrorT String (Reader Env) a
TCM предназначен для сообщения об ошибках и прохождения среды, например:
typeof (EVar v) = do
env <- ask
case M.lookup v env of
Nothing -> throwError $ "undefined variable" ++ v ++ "\n"
Just t - > return t
Теперь я хочу проверить тип выражений, поэтому у меня есть следующая функция, которая выполняет проверки:
typeof Exp :: Exp -> TCM Type
Он определен для всех случаев, кроме одного:
typeof (EFuncWithParams f l)
Я застрял здесь. Я думаю, что мне следует проверить тип f (я имею в виду, прежде всего, проверить, действительно ли это функция) и посмотреть, соответствуют ли типы аргументов, которые записаны в определении f, типам аргументов, которые фактически передаются. К сожалению, я новичок в хаскеле и понятия не имею, как правильно это выразить. Любые предложения будут высоко оценены :)
РЕДАКТИРОВАТЬ: ОК, это может не подразумеваться из того, что я писал здесь ранее, но EFuncWithParams Ident [Exp] на самом деле является вызовом функции (да, я знаю, что это несколько вводит в заблуждение), и я хочу иметь возможность вызывать такую функцию, как f(2 + 3, a, b[0]), поэтому я использовал TFunction [Exp]. Объявление и определение функции является оператором и определяется:
data Function_def =
Func Type_specifier Declarator Compound_stm
deriving (Eq,Ord,Show)
где декларатор:
data Declarator = FuncDec Ident Parameter_declarations
Объявления параметров — это список Type_specifiers и Idents.
Я думаю, что мне следует сохранить тип функции на карте при проверке ее объявления, а затем получить его здесь. Я имею в виду, что у меня также есть:
typeof_stm :: Stm -> TCM Type -- Function_def is a statement
Проблема в том, что у меня есть отдельная функция для операторов проверки типов, и я сомневаюсь, передается ли карта, используемая одной функцией (например, typeof_stm), автоматически другой (например, typeof). Я не вижу возможности, чтобы это произошло, но, возможно, я ошибаюсь.