在编译和将运行时误差视为汇编误差期间的表达



我正在Haskell中的简单编程语言解释器上工作,在定义标准库时,我遇到了一些麻烦。我希望将其定义为Toplevel的静态字符串,并与我的解释器一起编译:

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。此外,它不会给我任何关于解析或打字错误的反馈。如果parsetypecheck返回Left,我希望我的解释器根本不编译以下示例:

stdLibString = "≠²³¢©œęæśð"
-- Compilation error: "cannot parse definition"
stdLib = either (error . show) id $ parse stdLibStr >>= typecheck

我试图在为我的语言定义quaSiquotation时使用fail来实现这一目标,但是由于其他一些问题,因此不可能有这样的报价。

如何以最方便的方式进行操作?

如注释中所建议的,模板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的内联。

要使用此功能,必须在单独的模块中定义$()中调用的任何功能,而不是调用它。

最新更新