← Back to context

Comment by KPGv2

2 days ago

Yes, I'm writing a parser in Unison (in the Haskell family) for ASN.1 at the moment. It's so clean to write parsers with parser combinators.

For example Asn1Type can be of form Builtin, Referenced, or Constrained. So a sum type.

    parseType = Builtin <$> parseBuiltin <|> (Referenced <$> parseReferenced) <|> (Constrained <$> parseConstrained)

Assuming you have the parsers for Builtin, Referenced, and Constrained, you're golden. (Haskell PCs look very similar, possibly even exactly the same minus different parenthesis for operator precedence reasons.

Compare Parsy for Python, particularly the verbosity (this parses SELECT statements in SQL):

    select = seq(
    _select=SELECT + space,
    columns=column_expr.sep_by(padding + string(",") + padding, min=1),
    _from=space + FROM + space,
    table=table,
    where=(space >> WHERE >> space >> comparison).optional(),
    _end=padding + string(";"),

).combine_dict(Select)

The same thing in a FP-style language would be something like

    eq "SELECT" *> 
      Select 
      <*> (sepBy columnExpr (eq ",")) <* (eq "FROM") 
      <*> parseTable 
      <*> optional (eq "WHERE") <* eq ";"

which would feed into something like

    type Select = { cols: [ColumnExpr], table: Table, where: Optional Where}