First of all, when investigating type errors, you need to write down the types of function signatures that you know.
Here the solution may be of type
solve :: String -> String -> String -> [String] -> String
or
solve :: String -> String -> String -> [String] -> IO String
Depending on whether it should have any side effects when calculating the value. Having seen that you are using mapM
and return
everywhere, I assume that an IO
version might be intended.
Now, if you record a signature, you begin to receive much more meaningful error messages. For example, instead:
tmp.hs:19:16: Couldn't match expected type `Char' with actual type `[Char]' Expected type: [Char] Actual type: [[Char]] In the return type of a call of `solve' In the first argument of `return', namely `(solve (prefix ++ header ++ " ") "" sent dict)'
which doesn't make much sense, you get the following:
tmp.hs:14:8: Couldn't match expected type `IO String' with actual type `[a0]' In the expression: return prefix ++ header In the expression: if (header `elem` dict) then return prefix ++ header else return "" In an equation for `solve': solve prefix header [] dict = if (header `elem` dict) then return prefix ++ header else return ""
which shows exactly where the problem is. The application function has the highest priority in Haskell, so return prefix ++ header
equivalent to (return prefix) ++ header
, which definitely doesn't mean what you meant.
By the way, if I remove IO
from the return type, delete all return
and change the call by adding putStrLn
, the code compiles and works! The only problem is that it combines all the possible sentences together in one line without any restrictions.