سؤال

I want to make a function that takes a string "path" this is the path of a file that has only one line, I want to take this line and check it if it's a proper expression and if it is to build a tree out of this string, here is the code `

loadExpression :: String -> Tree Char
loadExpression path = do
 contents <- readFile path
 if checkIfProper $ filter (/=' ') contents
    then buildTreeFromString contents
    else EmptyTree  

`

But It gives me error "Couldn't match type IO' withTree' " . I know the IO string is different from the normal one but isn't <- suppost to do just that ? Converting IO string to a normal one. If I call buildTreeFromString with a string like "(1+2)*3" it works fine, same for the checkIfProper.

The whole error is :

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
هل كانت مفيدة؟

المحلول

readFile has type FilePath -> IO String, so your do block is in the IO monad. Your entire function therefore returns an IO (Tree Char), not a Tree Char, so you need to change your type signature.

EDIT: You can separate the effectual and pure parts of your function, by creating a function to load the tree from an input string. You can then pass the string from readFile into this function:

readTree :: String -> Tree Char
readTree contents =
 if checkIfProper $ filter (/=' ') contents
    then buildTreeFromString contents
    else EmptyTree

loadExpression then becomes:

loadExpression :: FilePath -> IO (Tree Char)
loadExpression path = do
  contents <- readFile path
  return (readTree contents)

or you can use fmap:

loadExpression = fmap readTree readFile
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top