anybody
anybody

Reputation: 121

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)"holdon"

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?

Upvotes: 1

Views: 222

Answers (3)

Reid Barton
Reid Barton

Reputation: 15029

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)

Upvotes: 0

Heatsink
Heatsink

Reputation: 504

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.

Upvotes: 6

ase
ase

Reputation: 13489

readThat (triple, str) = SomeDataType (read triple :: (Float, Float, Float)) 
                                      (read str :: String)

Quick and dirty.

Upvotes: 0

Related Questions