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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With