0

I'm trying to read from a file in Haskell, and i'm having trouble handling the data afterwards.

Basically, what i want to do is, read the file, and then create a matrix based on the data that was read. But it is a bit trickier than this. I'll explain:

Here's an example input file:

6 - number of lines in the matrix
7 - number of columns in the matrix
PA 3123
PB 11254
PC 790
PD 86214        
PE 114125
PF 36214

and the rest is the data itself.

Now, since in this example,the number of columns is seven, the matrix must be created the following way:

 Column 1  | Column 2  |  Column 3  |  Column 4 |  Column 5  |  Column 6  |  Column 7 

 3123/1       3123/2       3123/3       3123/4      3123/5       3123/6       3123/7

  ...          ...          ...          ...         ...          ...           ...

and the same for the others.

I've search the site for answers, and i've read some parts of the book Learn You a Haskell for Great Good!, and i was able to come up with this code:

-- Imports needed
import System.IO
import Data.List
import Data.Text


-- Runs the program
main = do
    putStrLn "Please insert the name of the file you want to process:"
    file <- getLine
    read_File file


-- Reads all file content
read_File file = do
h <- openFile file ReadMode
content <- hGetContents h
hClose h
handleFile content

-- Handles the content of the file
handleFile content = do
n1 <- getLine 
n2 <- getLine
-- here comes my big problem, how can i create the matrix properly?
putStrLn n1
putStrLn n2

This code compiles just fine, but there is an issue. I've put two putStrLn at the end, to verify that the file was properly read, but when i run it, i get no errors, but no data at all.

Thanks in advance!

PS: Here's the compilation process!

Compilation Process

4
  • What command are you using to run this code? I get test.hs:22:20: parse error on input ‘=’ when doing runhaskell test.hs Commented Nov 16, 2014 at 18:45
  • i use GHCI, ":l test.hs" and i don't get any error @MaxGabriel Commented Nov 16, 2014 at 18:47
  • @MaxGabriel i've edited it with an image from the command prompt Commented Nov 16, 2014 at 18:52
  • The formatting of your read_File and handleFile functions is incorrect; you need to indent the body of your do constructs. Haskell questions, particularly, need to be properly formatted as many questions are about incorrect parses caused by improper formatting. Commented Dec 5, 2014 at 16:15

1 Answer 1

1

You have two problems:

First, handleFile is reading from stdin - it should process the data in content:

handleFile content = do
  let lns = Prelude.lines content
      (n1:n2:rest) = lns  -- first two lines
  putStrLn $ "first line is: " ++ n1
  putStrLn $ "second line is: " ++ n2

Second, this is going to be a problem:

...
h <- openFile file ReadMode
content <- hGetContents h
hClose h
handleFile content
...

hGetContents uses lazy I/O - data is not read until it is needed. By performing hClose h you will be closing the file handle before any data is read.

You can fix this by performing the hClose after performing handleFile, e.g.:

content <- hGetContents h
handleFile content
hClose h

Alternatively, you can use readFile and not worry about opening or closing the file:

content <- readFile file
Sign up to request clarification or add additional context in comments.

8 Comments

it does not work only with the readFile option. Thank you! Can you now give some guidance on the matrix problem ?
another problem i spoted, is that, in your version, after the first two numbers the 'rest' seems to be empty, because when i try to print it out, it does not print anything...
Here is my code: lpaste.net/114404 Post your code and I'll take a look at it.
I get a type check error on line 25. Note that rest is a list of Strings, not a single String. Just use print rest to see what it looks like (use a small input file.)
can you give some hints, on how to create the matrix properly ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.