# How to Use `reads`

Albert Y. C. Lai, trebla [at] vex [dot] net

You have a `String`, it stands for a number or it is garbage, you want to parse out that number or call it a parse error. How to do it with `read`? Answer: use `reads` instead.

## Principle

The principle of using `reads` is exemplified by the following cases:

• ```reads "" :: [(Integer,String)]
```

The result is `[]`. This stands for parse errors.

• ```reads "34" :: [(Integer,String)]
```

The result is `[(34, "")]`. This stands for successful parses, and you get the number. Note that leading spaces are skipped first. (What about trailing spaces? See the next case.)

• ```reads "34   " :: [(Integer,String)]
reads "   34   " :: [(Integer,String)]
```

The result is `[(34, "   ")]`. Trailing data is isolated and served, in case you want to check it, or it contains other things you want to parse out.

```reads "34abc" :: [(Integer,String)]
```

The result is `[(34, "abc")]`.

• There is a 4th case of getting a list with 2 or more tuples. This does not happen with the default parsers. But you can make it happen when you write your own `Read` instance, if you want to support an ambiguous grammar, and so there can be multiple correct parses and you give/get them all in a huge list.

## Examples

The following allows trailing garbage, e.g., `34abc` is accepted:

```main = do
cs <- getLine
case reads cs :: [(Integer,String)] of
[(n, _)] -> print n
_ -> putStrLn "invalid input"
```

The following bans trailing data, e.g., `34abc` is rejected, since the pattern insists on empty trailing data; the user must enter `34`:

```main = do
cs <- getLine
case reads cs :: [(Integer,String)] of
[(n, "")] -> print n
_ -> putStrLn "invalid input"
```

Or perhaps you expect a number followed by a boolean, and that should be the end:

```main = do
cs <- getLine
case reads cs :: [(Integer,String)] of
[(n, s1)] -> case reads s1 of
-- type anontation unneeded because "not b" helps infer Bool
[(b, "")] -> putStrLn (show n ++ " " ++ show (not b))
[(_, _)] -> putStrLn "invalid, trailing data"
_ -> putStrLn "invalid second item"
_ -> putStrLn "invalid first item"
```

Another way, but this time you don't care where the parse error is:

```main = do
cs <- getLine
case myreads cs :: [(Integer,Bool,String)] of
[(n, b, "")] -> putStrLn (show n ++ " " ++ show (not b))
_ -> putStrLn "invalid input"

myreads cs0 = [ (x, y, cs2) | (x, cs1) <- reads cs0, (y, cs2) <- reads cs1 ]
```

Lastly, if you expect unique parses, you may as well forget lists and turn everything into `Maybe`:

```main = do
cs <- getLine
case myparse cs :: Maybe (Integer,Bool) of
Just (n, b) -> putStrLn (show n ++ " " ++ show (not b))
Nothing -> putStrLn "invalid input"

myparse cs0 = case [ (x, y, cs2) | (x, cs1) <- reads cs0, (y, cs2) <- reads cs1 ] of
[(x, y, "")] -> Just (x, y)
_ -> Nothing
```

## Typing

`reads` is ad-hoc polymorphic; which parser it chooses (`Integer` parser? `Double` parser? ```Maybe Integer``` parser?…) depends on which return type you choose, which in turn depends on context. Some cases can be inferred, and some other cases cannot be. For starters, there is no hope a standalone `reads cs` can have its type inferred; do not be surprised that more complex cases cannot be either.

(When in doubt, just give it a try. Add type annotations if the type checker fails.)

Examples of types choosing parsers:

```reads " 34,abc" :: [(Integer,String)]
[(34,",abc")]

[(340000.0,",abc")]

[('x',",abc")]

reads "Just 34,abc" :: [(Maybe Integer,String)]
[(Just 34,",abc")]

[((34,True),",abc")]
```

Example program that can be completely inferred:

```main = do
cs <- getLine
[(n,"")] -> print (n + length cs)
-- due to length, n::Int is forced
_ -> putStrLn "invalid input"
```

Example program that completely fails:

```main = do
cs <- getLine