2 ms·
They're not bad. They're just a pain to type out in detail every time. Here's an example signature from an F# library I like called FParsec: pipe2: Parser<
by munchler 3y ago
They're not bad. They're just a pain to type out in detail every time. Here's an example signature from an F# library I like called FParsec:
pipe2: Parser<'a,'u> -> Parser<'b,'u> -> ('a -> 'b -> 'c) -> Parser<'c,'u>
That's fine for documentation, but I'm glad it's not cluttering up the actual implementation, which starts like this:
let pipe2 (p1: Parser<'a,'u>) (p2: Parser<'b,'u>) f =
...
You can see how the code does explicitly specify the types of `p1` and `p2`, but doesn't bother spelling out the type of `f` or the return type. Although we are thinking in types the whole time, this sort of flexibility in the implementation is important for real-world functional code.
(For anyone wondering, this function takes two parsers and a function as input. It sends the output of each parser to the function, and the result is itself a parser. This is equivalent to a well-known abstract function called `liftA2` in a language that supports typeclasses, like Haskell.)
[0]: https://www.quanttec.com/fparsec/reference/primitives.html#members.pipe2 https://www.quanttec.com/fparsec/reference/primitives.html#m...
[1]: https://github.com/stephan-tolksdorf/fparsec/blob/master/FParsec/Primitives.fs https://github.com/stephan-tolksdorf/fparsec/blob/master/FPa...
[2]: https://hoogle.haskell.org/?hoogle=liftA2 https://hoogle.haskell.org/?hoogle=liftA2