Reputation: 15434
I have this:
data SomeData = SomeData Int Int
getDataFromUser :: SomeData
getDataFromUser = do
{
read (getLine)::SomeData;
}
This doesnt compile : Expected type String Actual type IO String
How I can fix it? I need this data deserialization...
Upvotes: 1
Views: 682
Reputation: 30227
You need to read up more on how Haskell IO works and make sure you understand it.
A couple of points on your example. If you want to use read
to deserialize to SomeData
, you need to provide a Read
instance for the type. You can use the default one:
data SomeData = SomeData Int Int deriving (Read)
Second: getLine
is an IO
action that returns a String
, not a String
; since read
wants a String
, this is the cause of your error. This is closer to what you want:
getDataFromUser :: IO SomeData
getDataFromUser = do str <- getLine
return (read str)
This can be simplified to the following, but make sure you understand the above example before you worry too much about this:
getDataFromUser :: IO SomeData
getDataFromUser = liftM read getLine
Upvotes: 7
Reputation: 40787
You're trying to treat getLine
as a String, but it's an IO String
— an IO action that, when executed, produces a string. You can execute it and get the resulting value from inside a do
block by using <-
, but since getDataFromUser
does IO, its type has to be IO SomeData
:
getDataFromUser :: IO SomeData
getDataFromUser = do
line <- getLine
return $ read line
More broadly, I would recommend reading a tutorial on IO in Haskell, like Learn You a Haskell's chapter on IO; it's very different from the IO facilities of most other languages, and it can take some time to get used to how things fit together; it's hard to convey a full understanding with answers to specific questions like this :)
Upvotes: 9