Why haskell use a type of ReadS a to represent a function?

function, haskell

Solution

A parser for things is a function from strings to lists of pairs of things and strings!

— Various sources

It aids in reasoning about programs to think about abstractions in terms of their intent, rather than their implementation. So yes, while `type ReadS a = String -> [(a, String)]`, that’s secondary to the actual goal of parsing things, and of chaining `ReadS` parsers together. As Rhymoid points out:

composeReads :: ReadS a -> ReadS b -> ReadS (a,b)

Conveys the intent of parser composition, and as a happy side effect is much more succinct, than the inlined equivalent:

composeReads
  :: (String -> [(a, String)])
  -> (String -> [(b, String)])
  -> (String -> [((a, b), String)])

It’s a good and obvious thing to factor out this repetition, not least because it’s good to avoid repetition, but also to increase as much as possible the amount of useful semantic content per line. And if we want to change things about how these parsers are implemented, then encapsulating them behind this alias is a small step that may let us avoid massive changes to every single usage site.

You see this repeated in the various parser combinator libraries such as Parsec, Attoparsec, and uu-parsinglib. A `Parser` is a `Parser` is a `Parser`, and the more like a black box these things are, the easier it is to play with their usage and implementation—separately.

Problem

I am reading the source code of `reads`. `reads` is defined as `reads :: Read a => ReadS a` So it simply returns `ReadS a` while a has to be a instance of `Read`. And `ReadS a` is defined as `type ReadS a = String -> [(a, String)]`, so the thing returned from `reads` is only a function that take a string and return an array of tuple. Then I wonder why just define `reads` without ReadS a. Just like `reads :: Read a => (String -> [(a, String)])`

Original source