2016-09-27 53 views
1

我對自然語言的一個小玩具的語義,用類似的話:Language.Haskell.Interpreter:這是手頭工作的正確工具嗎?

ran :: String -> Bool 
ran = (`elem` ["Bart", "Homer", "Marge"]) 

和:

bart :: String 
bart = "Bart" 

因此,例如,我可以有(ran bart) :: Bool,等等。

我想寫一個解析器,例如採用字符串"Bart ran"並返回True。我可能會使用Parsec。

但是,問題是能夠通過字符串調用函數。例如。從"ran"獲得功能ran。爲此,我認爲Language.Haskell.Interpreterinterpret功能可能是適當的。

所以我的問題是:

  1. 這是一個明智的方式做我想做的事?

  2. 如果是這樣,爲什麼不下面的工作,進入GHCI,在同一個目錄中ran給出了一個名爲Grammar.hs模塊定義如上:

    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)"}])" 

這表明導入不起作用,事實上,如果我嘗試類似Prelude函數,一切正常。

  • 爲什麼我獲得下列類型的錯誤(以及許多其他),如果我嘗試編譯相同的代碼在第二季度,(減去let):
  • No instance for MonadIO m0 arising from a use of runInterpreter

    回答

    2

    至於#2,您需要添加"Grammar"setImports列表,以及:

    runInterpreter $ do 
        loadModules ["HintDefs"] 
        setImports ["Prelude", "HintDefs"] 
        interpret "ran" (as :: String -> Bool) 
    

    至於#3,這是因爲runInterpreter在單子的選擇運行單態在:

    runInterpreter :: (MonadIO m, MonadMask m) 
           => InterpreterT m a 
           -> m (Either InterpreterError a) 
    

    所以你需要通過例如運行它選擇一個特定mIO

    main :: IO() 
    main = do 
        ran <- runInterpreter $ do 
         loadModules ["HintDefs"] 
         setImports ["Prelude", "HintDefs"] 
         interpret "ran" (as :: String -> Bool) 
        print $ ran <*> pure "John" 
    

    現在,#1,我不相信你需要的東西作爲提示這裏愚蠢強大。你可以維護一個字典String -> Bool功能鍵String鍵,像簡單的Map String (String -> Bool),然後用它來查找ran

    相關問題