我对自然语言有一个小玩具语义,用以下单词:
ran :: String -> Bool
ran = (`elem` ["Bart", "Homer", "Marge"])
和
bart :: String
bart = "Bart"
例如,我可以拥有(ran bart) :: Bool
,依此类推。
我想编写一个解析器,例如获取字符串"Bart ran"
并返回True
。我可能会使用Parsec。
然而,问题是能够通过字符串调用函数。例如。从"ran"
转到函数ran
。为此,我认为Language.Haskell.Interpreter
的interpret
功能可能是合适的。
所以我的问题是:
这是一种明智的方式来做我想做的事吗?
Grammar.hs
醇>
我收到错误:
ran
这表明导入不起作用,事实上,如果我尝试使用Prelude函数进行类似的操作,一切都会正常工作。
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: \8216ran\8217\n Perhaps you meant \8216tan\8217 (imported from Prelude)"}])"
let
没有任何实例
答案 0 :(得分:2)
对于#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 -> Bool
键加密的String
函数字典,类似于Map String (String -> Bool)
,然后用它来查找ran
等。