Language.Haskell.Interpreter:这是适合手头工作的工具吗?
Language.Haskell.Interpreter: is this the right tool for the job at hand?
我对自然语言有一点玩具语义,像这样的词:
ran :: String -> Bool
ran = (`elem` ["Bart", "Homer", "Marge"])
和:
bart :: String
bart = "Bart"
例如,我可以有 (ran bart) :: Bool
,依此类推。
我想编写一个解析器,例如接受字符串 "Bart ran"
和 returns True
。我可能会为此使用秒差距。
但是,问题在于能够通过字符串调用函数。例如。从 "ran"
到函数 ran
。为此,我认为 Language.Haskell.Interpreter
的 interpret
函数可能是合适的。
所以我的问题是:
这是做我想做的事情的明智方法吗?
如果是这样,为什么下面的工作不起作用,进入 GHCi,给定一个名为 Grammar.hs
的模块,该模块位于与上面定义的 ran
相同的目录中:
let a = runInterpreter $ do
loadModules ["Grammar"]
setImports ["Prelude"]
interpret "ran" (as :: String -> Bool)
let b = do
x <- a
return $ x <*> pure "John"
b
我收到错误:
"Left (WontCompile [GhcError {errMsg = "<interactive>:2:1:\n Not in scope: 16ran17\n Perhaps you meant 16tan17 (imported from Prelude)"}])"
这表明导入无效,事实上,如果我尝试使用 Prelude 函数进行类似操作,一切正常。
- 如果我尝试编译与 Q2 中相同的代码(减去
let
),为什么会出现以下类型错误(以及许多其他错误):
No instance for MonadIO m0
arising from a use of runInterpreter
至于 #2,您还需要将 "Grammar"
添加到 setImports
列表中:
runInterpreter $ do
loadModules ["HintDefs"]
setImports ["Prelude", "HintDefs"]
interpret "ran" (as :: String -> Bool)
至于#3,是因为runInterpreter
在monad的选择上是单态的运行它在:
runInterpreter :: (MonadIO m, MonadMask m)
=> InterpreterT m a
-> m (Either InterpreterError a)
因此您需要通过 运行 选择一个特定的 m
,例如IO
:
main :: IO ()
main = do
ran <- runInterpreter $ do
loadModules ["HintDefs"]
setImports ["Prelude", "HintDefs"]
interpret "ran" (as :: String -> Bool)
print $ ran <*> pure "John"
现在,关于 #1,我不认为您需要像 HInt 一样强大的东西。你可以只维护一个由 String
键键入的 String -> Bool
函数的字典,像 Map String (String -> Bool)
这样简单的东西,然后用它来查找 ran
等
我对自然语言有一点玩具语义,像这样的词:
ran :: String -> Bool
ran = (`elem` ["Bart", "Homer", "Marge"])
和:
bart :: String
bart = "Bart"
例如,我可以有 (ran bart) :: Bool
,依此类推。
我想编写一个解析器,例如接受字符串 "Bart ran"
和 returns True
。我可能会为此使用秒差距。
但是,问题在于能够通过字符串调用函数。例如。从 "ran"
到函数 ran
。为此,我认为 Language.Haskell.Interpreter
的 interpret
函数可能是合适的。
所以我的问题是:
这是做我想做的事情的明智方法吗?
如果是这样,为什么下面的工作不起作用,进入 GHCi,给定一个名为
Grammar.hs
的模块,该模块位于与上面定义的ran
相同的目录中:let a = runInterpreter $ do loadModules ["Grammar"] setImports ["Prelude"] interpret "ran" (as :: String -> Bool) let b = do x <- a return $ x <*> pure "John" b
我收到错误:
"Left (WontCompile [GhcError {errMsg = "<interactive>:2:1:\n Not in scope: 16ran17\n Perhaps you meant 16tan17 (imported from Prelude)"}])"
这表明导入无效,事实上,如果我尝试使用 Prelude 函数进行类似操作,一切正常。
- 如果我尝试编译与 Q2 中相同的代码(减去
let
),为什么会出现以下类型错误(以及许多其他错误):
No instance for
MonadIO m0
arising from a use ofrunInterpreter
至于 #2,您还需要将 "Grammar"
添加到 setImports
列表中:
runInterpreter $ do
loadModules ["HintDefs"]
setImports ["Prelude", "HintDefs"]
interpret "ran" (as :: String -> Bool)
至于#3,是因为runInterpreter
在monad的选择上是单态的运行它在:
runInterpreter :: (MonadIO m, MonadMask m) => InterpreterT m a -> m (Either InterpreterError a)
因此您需要通过 运行 选择一个特定的 m
,例如IO
:
main :: IO ()
main = do
ran <- runInterpreter $ do
loadModules ["HintDefs"]
setImports ["Prelude", "HintDefs"]
interpret "ran" (as :: String -> Bool)
print $ ran <*> pure "John"
现在,关于 #1,我不认为您需要像 HInt 一样强大的东西。你可以只维护一个由 String
键键入的 String -> Bool
函数的字典,像 Map String (String -> Bool)
这样简单的东西,然后用它来查找 ran
等