0
votes

I am a beginner and I was trying to write a function that check if a string can be interpreted to number or not. Here is my code:

string' xs = if (all isDigit xs == False)
             then "can not be interpreted"
             else read xs::Int 

But it keeps reporting the error " Couldn't match expected type ‘[Char]’ with actual type ‘Int’ " I don't know why, has someone ever met this problem?

1
What is the type of string' - is it string' :: String -> String or string' :: String -> Int? In haskell, you can't have a function that returns one of two different types based on runtime properties of the input.Daniel Martin
You might also like reads :: String -> [(Int, String)], which will check that the input is well-formed for you, returning [] if not (and a list with the successful parse and whatever was left unparsed if so).Daniel Wagner
Style comment: consider using not (...) instead of (...) == False. This is a matter of taste, but the first looks more "natural". Alternatively, remove that completely and swap the then/else branches. (Daniel's suggestion above about reads would be even better.)chi

1 Answers

4
votes

Both branches of your if-then-else need to have the same type. Your "then" branch has type [Char] and your "else" branch has type Int. It seems like your "then" branch should result in some sort of error. In this case you can use error, which has a polymorphic type and can be used instead.

A better solution (suggested in the comment section) would be to use the Either type, which can return one of two options (Left or Right).

string' xs = if (all isDigit xs == False)
             then Left "can not be interpreted"
             else Right (read xs::Int)

Another common thing to do would be to use the Maybe type

string' xs = if (all isDigit xs == False)
             then Nothing
             else Just (read xs::Int)