Convert String to List/Array of Numbers

You should use:
convert = map (map read . words) . lines
Or:
convert x = (map (map read . words) . lines) x
Or, yet:
convert x = map (map read . words) . lines $ x
The function application occurs before the dot composition!
On Wed, Sep 8, 2010 at 14:24, Lorenzo Isella
Hi Daniel, Thanks for your help. I have a couple of questions left (1) The first one is quite down to earth. The snippet below
--------------------------------------------------- main :: IO ()
main = do txt <- readFile "mydata.dat"
let dat = convert txt
print dat -- this prints out my chunk of data
return ()
convert x = lines x
-----------------------------------------------
pretty much does what it is supposed to do, but if I use this definition of convert x
convert x = map (map read . words) . lines x
I bump into compilation errors. Is that the way I am supposed to deal with your function?
(2) This is a bit more about I/O in general. I start an action with "do" to read some files and I define outside the action some functions which are supposed to operate (within the do action) on the read data. Is this the way it always has to be? I read something about monads but did not get very far (and hope that they are not badly needed for simple I/O). Is there a way in Haskell to have the action return to the outside world e.g. the value of dat and then work with it elsewhere? That is what I would do in Python or R, but I think I understood that Haskell's philosophy is different... Am I on the right track here? And what is the benefit of this?
Cheers
Lorenzo
On 09/08/2010 04:06 PM, Daniel Fischer wrote:
On Wednesday 08 September 2010 15:31:19, Lorenzo Isella wrote:
Dear All, I must be stuck on something pretty basic (I am struggling badly with I/O). Let us assume you have a rather simple file mydata.dat (3 columns of integer numbers), see below.
1246191122 1336 1337 1246191142 1336 1337 1246191162 1336 1337 1246191182 1336 1337 1246191202 1336 1337 1246191222 1336 1337 1246191242 1336 1337 1246191262 1336 1337 1246191282 1336 1337 1246191302 1336 1337 1246191322 1336 1337 1246191342 1336 1337 1246191362 1336 1337 1246191382 1336 1337 1246191402 1336 1337 1246191422 1336 1337
Now, my intended pipeline could be
read file as string--> convert to list of integers-->pass it to hmatrix (or try to convert it into a matrix/array). Leaving aside the last step, I can easily do something like
let dat=readFile "mydata.dat"
in the interactive shell and get a string,
Not quite. `dat' is the IO-action that reads the file, of type (IO String) and not a String. In a programme, you'd do something like
main = do ... -- argument parsing perhaps txt<- readFile "mydata.dat" let dat = convert txt doSomething with dat
but I am having problems in
converting this to a list or anything more manageable (where every entry is an integer number i.e. something which can be summed, subtracted etc...). Ideally even a list where every entry is a row (a list in itself) would do.
Depending on what the reult type should be, different solutions are required. The simplest solutions for such a file format are built from
read -- to convert e.g. "135" to 135 lines :: String -> [String] words :: String -> [String] map :: (a -> b) -> [a] -> [b]
If you want a flat list of Integers from that file,
convert = map read . words
will do. First, `words' splits the String on whitespace (spaces and newlines), producing a list of digit-strings, those are then read as Integers.
If you want a list of lists, each line its own list inside the top level list,
convert = map (map read . words) . lines
is what you want.
If you want to convert each line into a different data structure, say (Integer, Double, Int64), the general form would still be
convert = map parseLine . lines
and parseLine would depend on the structure you want. For the above,
parseLine str = case words str of (a : b : c : _) -> (read a, read b, read c) _ -> error "Bad line format"
would be a solution.
For any but the simplest formats, you should write a real parser to deal with possible bad formatting though (writing parsers is fun in Haskell).
I found online this suggestion
http://bit.ly/9jv1WG but I am not sure if it really applies to this case. Many thanks
Lorenzo
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- Rafael Gustavo da Cunha Pereira Pinto -- Rafael Gustavo da Cunha Pereira Pinto
participants (1)
-
Rafael Gustavo da Cunha Pereira Pinto