Reading something from a file and putting it under a data type
I have a file that contains this:
(Float,Float,Float)"sometext"
(Float,Float,Float)"sometext"
(Float,Float,Float)"sometext"
...
...
and I would like my program to read a line from the file, put the (Float,Float,Float) into a tripple and "sometext" into a String and all of it under a new data type so the whole thing would look like this:
SomeDataType (Float,Float,Float) "sometext"
I got this so far:
readFromDisc filePath = do
fileHandle <- openFile "/tmp/lala.txt" ReadMode
contents <- hGetContents fileHandle
putStrLn $ readOneLine contents
If the file contains this:
(5.0,6.0,7.0)"faraway"
(8.0,9.0,0.0)"h开发者_如何学Gooldon"
I get:
"(5.0,6.0,7.0)\"faraway\""
Now, since I get that as a String I was thinking of using
breakInput input = break (=='"') input
To get this:
("(5.0,6.0,7.0)","\"faraway\"")
Which is a pair of strings, and I was going to use something to parse the tripple and the text out of it, but all of it doesn't feel right.
Is there a better way to do this?
Use the reads
function. It will parse the matching part at the beginning of the string, and return the rest of the string.
parseLine :: String -> [((Double, Double, Double), String)]
parseLine line = do
(tuple, line') <- reads line
(string, _) <- reads line'
return (tuple, string)
-- parseLine "(5.0, 6.0, 7.0)\"faraway\"" ---> ((5.0, 6.0, 7.0), "faraway")
This will return a list of matches, and ignore junk at the end of the line. Since your particular case has an unambiguous parse, only one match will be produced by a successful parse.
readThat (triple, str) = SomeDataType (read triple :: (Float, Float, Float))
(read str :: String)
Quick and dirty.
A quick hack, if you don't care about handling errors:
data SomeDataType = SomeDataType (Float, Float, Float) String
deriving Read
readOneLine s = read ("SomeDataType " ++ s)
精彩评论