• Reading data from text file

    From Archangel M.@21:1/5 to All on Fri Jul 1 11:24:52 2016
    Hi,

    I'm sorry if this question is too basic, but I could not find a simple
    solution that satisfies me, and I was not able to find a solution on the
    web.

    Suppose I have to read a data structure from a text file (space
    separated), one data item per line. My first tentative would be

    ====================================================================

    data Person = Person {name :: String, surname :: String, age :: Int, ...
    dozens of other fields} deriving (Show,...)

    main = do
    string <- readFile "filename.txt"
    let people = readPeople string
    do_something people

    readPeople s = map (readPerson.words) (lines s)

    readPerson row = Person (read(row!!0)) (read(row!!1)) (read(row!!2)) (read(row!!3)) ... (read(row!!dozens))

    ====================================================================

    This code works, but the code for readPerson is terrible: I have to
    copy-paste the read(row!!n)) for all fields in my data structure!

    So, as a second attempt, I think that I might exploit Currying of the
    Person function, and pass it the arguments one at the time.

    Uhm, there must be something in Hoogle, but I cannot figure out the type signature ... Never mind, it looks simple enough and I can write it myself:

    ===================================================================

    readPerson row = readFields Person row

    readFields f [x] = (f x)
    readFields f (x:xs) = readFields (f (read x)) xs

    ===================================================================

    Ahh, looks much better code!

    But, it does not compile! "Occurs check: cannot construct the infinite
    type: t ~ String -> t"

    Indeed, the function "f" I am passing to readFields has a different type signature in each invocation; that's why I could not figure its type
    signature ...

    So, my question is: what is the simplest way to read a data structure
    with many fields?

    Thank you for your suggestion and sorry if the question is a dumb one (I
    am still learning).

    Archangel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From endlessboomcapitalism@gmail.com@21:1/5 to Archangel M. on Tue Jul 12 10:35:06 2016
    On Friday, July 1, 2016 at 5:24:55 AM UTC-4, Archangel M. wrote:
    Hi,

    I'm sorry if this question is too basic, but I could not find a simple solution that satisfies me, and I was not able to find a solution on the
    web.

    Suppose I have to read a data structure from a text file (space
    separated), one data item per line. My first tentative would be

    ====================================================================

    data Person = Person {name :: String, surname :: String, age :: Int, ... dozens of other fields} deriving (Show,...)

    main = do
    string <- readFile "filename.txt"
    let people = readPeople string
    do_something people

    readPeople s = map (readPerson.words) (lines s)

    readPerson row = Person (read(row!!0)) (read(row!!1)) (read(row!!2)) (read(row!!3)) ... (read(row!!dozens))

    ====================================================================

    This code works, but the code for readPerson is terrible: I have to copy-paste the read(row!!n)) for all fields in my data structure!

    So, as a second attempt, I think that I might exploit Currying of the
    Person function, and pass it the arguments one at the time.

    Uhm, there must be something in Hoogle, but I cannot figure out the type signature ... Never mind, it looks simple enough and I can write it myself:

    ===================================================================

    readPerson row = readFields Person row

    readFields f [x] = (f x)
    readFields f (x:xs) = readFields (f (read x)) xs

    ===================================================================

    Ahh, looks much better code!

    But, it does not compile! "Occurs check: cannot construct the infinite
    type: t ~ String -> t"

    Indeed, the function "f" I am passing to readFields has a different type signature in each invocation; that's why I could not figure its type signature ...

    So, my question is: what is the simplest way to read a data structure
    with many fields?

    Thank you for your suggestion and sorry if the question is a dumb one (I
    am still learning).

    Archangel

    not lazy enuf

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)