Well basically this is just regular record synax:
data Parser a b = P {
runParser :: Stream a -> [(b, Stream a)]
}
It means that the Parser a b
data type has one data constructor. A data constructor named P
, and that constructor has one argument: a "field" called runParser
, and that field has type Stream a -> [(b, Stream a)]
.
This pattern is quite common in Haskell and in functional programming in general. Functions are "first class citizens". It means that functions can be passed as arguments, a function can return another function (in fact due to currying this happens very often in Haskell), and we can store (references to) function in a data constructor.
We can for example create a Parser Int Char
type with:
P (\_ -> []) :: Parser Int Char
So here we constructed a Parser Int Char
and the argument, a single function, maps any value to an empty list.
Or another example:
P (\x -> [('a', x), ('b', x)]) :: Parser Int Char
Here we thus map our Stream a
object x
, to a list of 2-tuples, one with 'a'
as first element, and one with 'b'
as first element. Each time we pick x
as second element.
Or we can define a function, and pass a reference to that function:
f :: Stream Int -> [(Char, Stream Int)]
f x = [('a', x)]
P f :: Parser Int Char