Выражение Eval во время компиляции и обработка ошибок времени выполнения как ошибок компиляции - PullRequest
1 голос
/ 20 марта 2019

Я работаю над простым интерпретатором языка программирования в Haskell, и у меня возникли некоторые проблемы при определении стандартной библиотеки.Я хотел бы, чтобы он был определен как статическая строка на верхнем уровне и скомпилирован вместе с моим интерпретатором:

stdLibStr :: String
stdLibStr = "id a := a;;"

parse :: String -> Either Error UntypedModule
typecheck :: UntypedModule -> Either Error TypedModule

-- constexpr
stdLib :: TypedModule
stdLib = either (error . show) id $ parse stdLibStr >>= typecheck

Однако модель выше не будет оценивать stdLib во время компиляции.Более того, это не даст мне никаких отзывов ни об ошибке разбора, ни о проверке типов.Я хотел бы, чтобы мой интерпретатор просто не компилировался, если либо parse, либо typecheck возвращает Left, как в следующем примере:

stdLibString = "≠²³¢©œęæśð"

-- Compilation error: "cannot parse definition"
stdLib = either (error . show) id $ parse stdLibStr >>= typecheck

Я пытался добиться этого с помощью fail при определении QuasiQuotation длямой язык, но из-за некоторых других проблем невозможно получить такую ​​цитату.

Как это сделать наиболее удобным способом?

1 Ответ

1 голос
/ 22 марта 2019

Как предлагается в комментариях, шаблон Haskell - способ сделать это.Приведенная ниже функция обрабатывает два случая:

compileTime :: Lift a => Either String a -> Q Exp
compileTime (Right a) = lift a
compileTime (Left err) = fail err

Она может быть вызвана как $(compileTime (typecheck =<< parse stdLibStr)).Или он достаточно короткий, чтобы вместо него вставить either fail lift.

Чтобы использовать это, любая функция, вызываемая в $(), должна быть определена в отдельном модуле, а не в том месте, где она вызывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...