您可以使用hint http://hackage.haskell.org/package/hint包,或plugins http://hackage.haskell.org/package/plugins。我将向您展示前者(部分原因是我的 Windows 安装显然有点损坏,因为 cabal 不同意我安装了 C 的信念,因此 cabal 安装插件失败)。
字符串 -> 函数很简单:
import Language.Haskell.Interpreter
getF :: String -> IO (Either InterpreterError (Float -> Float))
getF xs = runInterpreter $ do
setImports ["Prelude"]
interpret xs (as :: Float -> Float)
您可能想要将其他模块添加到导入列表中。测试结果为
ghci> getF "sin" >>= \(Right f) -> print $ f (3.1415927/2)
1.0
ghci> getF "(\\x -> if x > 5.0 then 5.0 else x)" >>= \(Right f) -> print $ f 7
5.0
(注意转义字符的转义\
.)
错误信息
您可能已经注意到,结果包装在 Either 数据类型中。Right f
是正确的输出,而Left err
给出一个InterpreterError
消息,这非常有帮助:
ghci> getF "sinhh" >>= \(Left err) -> print err
WontCompile [GhcError {errMsg = "Not in scope: `sinhh'\nPerhaps you meant `sinh' (imported from Prelude)"}]
示例玩具程序
当然,你可以使用either
用你的代码来处理这个问题。让我们举一个假例子respond
。你真正的将包含你的程序的所有数学知识。
respond :: (Float -> Float) -> IO ()
respond f = do
-- insert cunning numerical method instead of
let result = f 5
print result
然后,您的程序的一个简单的、一次性的、无用的版本可能是
main =
putStrLn "Enter your function please:"
>> getLine
>>= getF
>>= either print respond
会话示例
ghci> main
Enter your function please:
\x -> x^2 + 4
29.0
ghci> main
Enter your function please:
ln
WontCompile [GhcError {errMsg = "Not in scope: `ln'"}]
它为您进行类型检查:
ghci> main
Enter your function please:
(:"yo")
WontCompile [GhcError {errMsg = "Couldn't match expected type `GHC.Types.Float'\n with actual type `GHC.Types.Char'"}]