hendl <- openFile fileName ReadMode loadFacts <- hGetContents hendl qs <- return (table (read loadFacts)) run qs hClose hendl 

here is a fragment of the function, please explain what reads and returns do here

If anything, here are the rub and table definitions

  run::Table -> IO () table::Facts->Table 

@alexlz I still have a question about the read function - we pass it a pointer to the file, and it reads it (the table function has the form

 table::Facts->Table, где type Fact = (String,[(String,Bool)]) type Facts = [Fact] ) а входной файл имеет вид [("aa1", [("bb", True), ("cc", False),]), ("aa2", [("bb", True), ("cc", True),])] 

And how is reading? Line by line or every tuple reads?

  • one
    read does not read any file. At its input, the string is read :: Read a => String -> a , the result is of type a , in your case Facts. Reading a file from you is hGetContents. You can read and show override for your data type (I don’t remember about type aliases, maybe not). So it reads everything at once. By the way, do you have commas there? (before square brackets). Although, I don’t know how the file is read taking into account laziness. - alexlz
  • and what line is served read to the input (I mean, which line of the input file)? or does loadFacts immediately take the form [(String, [(String, Bool)])]? - Pavel
  • one
    And what is her parameters? loadFacts , which is the content (all - hGetContents) of fileName. ("immediately" is in the process of work, do not forget hGetContents :: Handle -> IO String ) hGetContents :: Handle -> IO String . And loadFacts is of type String. Parsing and converting to a value of type Facts performs a read. - alexlz
  • ATP, but because of laziness, it is not processed on the fly? and how then to build a table? As far as reading? - Pavel
  • one
    In general, it is on the fly, as needed. And reading from a file (at least logically) occurs as the table needs. True, the read logic intervenes here, which can force you to read everything (at the moment when any Facts element is needed). If you need to build before what is necessary by logic (for example, because of efficiency, but here you need code analysis and / or profiling) - force it. Functions seq , $! - alexlz

1 answer 1

  1. run performs the calculation contained in the gs variable.
  2. return (type a -> ma) - creates this calculation. In principle, it does not seem to be necessary here, i.e. (if I'm not confusing) two lines

    qs <- return (table (read loadFacts))
    run qs

are equivalent

 run (table (read loadFacts)) 

where read is of type String -> Facts Another write option

 let gs = table (read loadFacts)) run gs 

For clarity, you can rewrite it without do-notations, in terms of combinators >== and return