0

Before to mark this question as duplicated, I already read this topic: Haskell read Integer and list of lists from file and the solution doesn't solve my problem.

I'm trying to read the content in a File that contains this structure:

String, String, [(Int, Int, Int)]

The file looks something like this:

Name1   22/05/2018  [(1, 5, 10), (2, 5, 5), (3, 10, 40)]    
Name2   23/05/2018  [(1, 10, 10), (2, 15, 5), (3, 50, 40),(4,20,5)]    
Name3   22/05/2018  [(4, 2, 1), (5, 2, 2), (6, 50, 3), (1,2,3)]    
Name4   23/05/2018  [(1, 3, 10), (2, 1, 5), (3, 2, 40), (6,20,20)]

In Haskell, I created this function to read the contents of the file and "convert" this content to my custom type.

rlist :: String -> [(Int, Int, Int)]
rlist = read

loadPurchases :: IO [(String, String, [(Int, Int, Int)])]
loadPurchases = do s <- readFile "tes.txt"
                   return (glpurch (map words (lines s)))

glpurch :: [[String]] -> [(String, String, [(Int, Int, Int)])]
glpurch [] = []
gplpurch ([name, dt, c]:r) = (name, dt, (rlist c)) : gplpurch r

But when I try to execute the "loadPurchases" function, I get this error: Non-exhaustive patterns in function glpurch.

Using :set -Wall, I received this help message:

<interactive>:6:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for `glpurch':
    Patterns not matched:
        ([]:_:_)
        ([_]:_)
        ([_, _]:_)
        ((_:_:_:_:_):_)

My problem is how to create all these conditions.

I will be very grateful if anyone can help me create those conditions that are likely to determine the "stopping condition"

3
  • Could you try doing ((name : dt : c : _) : r) instead? Commented Jun 7, 2018 at 18:40
  • Your tips almost worked. I do this: glpurch ((name : dt : c : _) : r) = (name, dt, (rlist c)) : glpurch r, but now I get this message: [("Name1","22/05/2018",*** Exception: Prelude.read: no parse Commented Jun 7, 2018 at 18:44
  • 1
    In GHCi try words "Name4 23/05/2018 [(1, 3, 10), (2, 1, 5), (3, 2, 40), (6,20,20)]" and see what you're getting. Then type it !! 2 to see what the value of c is that is passed to rlist. Notice how that is only part of the list. Commented Jun 7, 2018 at 19:22

2 Answers 2

6

You are only matching lists of length 3 when in fact there are many more words on each line. Just try it in GHCi:

> words "Name1   22/05/2018  [(1, 5, 10), (2, 5, 5), (3, 10, 40)]"
["Name1","22/05/2018","[(1,","5,","10),","(2,","5,","5),","(3,","10,","40)]"]

You probably want to recombine all words past the first two:

glpurch ((name : dt : rest) :r) = (name, dt, (rlist $ unwords rest)) : gplpurch r
Sign up to request clarification or add additional context in comments.

2 Comments

Yes, that was exactly it. Another solution would be to remove the whitespace between the commas in the list?
I remove all the whitespaces in file, and solve with your and @Welperooni suggestions. Thank you very much guys.
0

To solve my problem, I did what @Welperooni and @Thomas M. DuBuisson suggested.

I added this code to my function:

glpurch ((name: dt: c: _): r) = (name, dt, (read c :: [(Cod, Quant, Price)

And I removed the blanks that were in the list in my file, these spaces made the division of the text not done correctly.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.