I am watching a tutorial on parsers in haskell https://www.youtube.com/watch?v=9FGThag0Fqs. The lecture starts with defining some really basic parsers. These are to be used together to create more complicated parsers later. One of the basic parsers is item. This is used to extract a character from the string we are parsing.
All parsers have the following type:
type Parser a = String -> [(a, String)]
The parser item is defined like this:
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)]
I am not so used to this syntax, so it looks strange to me. I would have written it:
item' :: Parser Char
item' [] = []
item' (x:xs) = [(x,xs)]
Testing it in ghci indicates that they are equal:
*Main> item ""
[]
*Main> item "abc"
[('a',"bc")]
*Main> item' ""
[]
*Main> item' "abc"
[('a',"bc")]
The lecturer makes a short comment about thinking it looks clearer, but I disagree. So my questions are:
Are they indeed completely identical? Why is the lambda version clearer?
I believe this comes from the common practice of writing
f :: Type1 -> ... -> Typen -> Result
f x1 ... xn = someResult
where we have exactly n
function arrows in the type, and exactly n
arguments in the left hand side of the equation. This makes it easy to relate types and formal parameters.
If Result
is a type alias for a function, then we may write
f :: Type1 -> ... -> Typen -> Result
f x1 ... xn y = something
or
f :: Type1 -> ... -> Typen -> Result
f x1 ... xn = \y -> something
The latter follows the convention above: n
arrows, n
variables in the left hand side. Also, on the right hand side we have something of type Result
, making it easier to spot. The former instead does not, and one might miss the extra argument when reading the code quickly.
Further, this style makes it easy to convert Result
to a newtype instead of a type alias:
newtype Result = R (... -> ...)
f :: Type1 -> ... -> Typen -> Result
f x1 ... xn = R $ \y -> something
The posted item :: Parser Char
code is an instance of this style when n=0
.
Why you should avoid equational function definitions (by Roman Cheplyaka): http://ro-che.info/articles/2014-05-09-clauses
Major Points from the above link:
This doesn't explain the lambda though..
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