Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In what scenarios does Haskell's `reads` return more than one list item?

Tags:

I can do the following:

Prelude> reads "1 2 3" :: [(Int, String)]
[(1," 2 3")]
Prelude> reads "(1,2) (3,4)" :: [((Int, Int), String)]
[((1,2)," (3,4)")]
Prelude> reads "(1,2)(3,4)" :: [((Int, Int), String)]
[((1,2),"(3,4)")]
Prelude> reads "(1,2)\n(3,4)" :: [((Int, Int), String)]
[((1,2),"\n(3,4)")]
Prelude> reads "(1,2)    (3,4)" :: [((Int, Int), String)]
[((1,2),"    (3,4)")]

I can derive Read and get reads to read those too. But I've never gotten reads to return more than one tuple in the list. Why does reads return a list?

like image 621
Ana Avatar asked Dec 31 '11 17:12

Ana


People also ask

How do I read a list in Haskell?

Use getContents to get all input from stdin . It does so lazily, so don't worry about running out of memory. Then separate it into lines with lines (or write your own function to divide it into lines for practice). This makes a [String] with each list element being a line in the input.

Can Haskell lists have different types?

Recall earlier that Haskell has many different kinds of types, such as * for value-containing types, [*] for type-level lists, etc. Haskell also has a special kind called Symbol from the module GHC.

What is nil Haskell?

The Nil constructor is an empty list. It contains no objects. So any time you're using the [] expression, you're actually using Nil . Then the second constructor concatenates a single element with another list.


2 Answers

None of the standard instances do so, but it's intended for ambiguous parses; since this is not really very useful, and parsers that use this functionality would be very inefficient, reads's return value is for all practical purposes a Maybe masquerading as a [].

The Report's definition of read reveals the intended meaning of multiple parses:

read    :: (Read a) => String -> a  
read s  =  case [x | (x,t) <- reads s, ("","") <- lex t] of  
              [x] -> x  
              []  -> error "PreludeText.read: no parse"  
              _   -> error "PreludeText.read: ambiguous parse"

So: historical reasons, basically.

like image 129
ehird Avatar answered Nov 15 '22 12:11

ehird


You can define Read instances for your datatypes which could return more than one item in reads. I haven't come across a situation where it would make sense, but it's possible.

like image 42
Daniel Fischer Avatar answered Nov 15 '22 12:11

Daniel Fischer