我想创建一个带字符串“path”的函数,这是一个只有一行的文件的路径,我想取这行并检查它是否是一个正确的表达式,如果是构建一个这个字符串中的树,这里是代码 `
loadExpression :: String -> Tree Char
loadExpression path = do
contents <- readFile path
if checkIfProper $ filter (/=' ') contents
then buildTreeFromString contents
else EmptyTree
`
但是它给了我错误“无法匹配类型IO' with
树'”。我知道IO字符串与普通字符串不同但是<-
支持不是这样做的吗?将IO字符串转换为普通字符串。如果我使用buildTreeFromString
之类的字符串来呼叫"(1+2)*3"
,那么checkIfProper
就可以正常工作了。
整个错误是:
Couldn't match type `IO' with `Tree'
Expected type: Tree String
Actual type: IO String
In the return type of a call of `readFile'
In a stmt of a 'do' block: contents <- readFile path
答案 0 :(得分:4)
readFile
的类型为FilePath -> IO String
,因此您的do
块位于IO
monad中。因此,您的整个函数返回IO (Tree Char)
,而不是Tree Char
,因此您需要更改类型签名。
编辑:您可以通过创建一个从输入字符串加载树的函数来分离函数的有效部分和纯部分。然后,您可以将readFile
中的字符串传递给此函数:
readTree :: String -> Tree Char
readTree contents =
if checkIfProper $ filter (/=' ') contents
then buildTreeFromString contents
else EmptyTree
然后 loadExpression
成为:
loadExpression :: FilePath -> IO (Tree Char)
loadExpression path = do
contents <- readFile path
return (readTree contents)
或者您可以使用fmap
:
loadExpression = fmap readTree readFile