Optional parser in elm/parser

If I am parsing a string that has a pattern like “prefix?rest”, should I express the prefix parsing with oneOf [ prefixParser, spaces] or is there something simpler that doesn’t need to use spaces?

I’m a bit confused by the uses of spaces, when there are no spaces in the example string. Perhaps a slightly more complete example would help?

meanwhile, here is something I’ve used (this one did have some spaces, but depends on your syntax)

optionalPrefix : MessageParser (Maybe String)
optionalPrefix =
  inContext "parsing a prefix" <|
    oneOf
      [ succeed Just
        |. symbol (Token ":" "Expecting line to start with :")
        |= prefix
        |. spaces
      , succeed Nothing
      ]

In this case I want some data if present, but you could have them both succeed () if you don’t.

1 Like

I was using spaces since I assumed it would match on no space, and I wasn’t aware of using succeed Nothing. succeed Nothing is what I was looking for.

Why not oneOf [ prefixAndRestParser, restParser ]?

1 Like

Why not oneOf [ prefixAndRestParser, restParser ]?
I basically had that typed out, but checked my code for examples :laughing:

2 Likes

I might revisit this later if I use elm/parser for other work. I would use the succeed with no implementation first because it lets me build up smaller parsers with simpler names that I can sequence together.

The approach I was suggesting is the same, you also build smaller parsers.
For example you’d build restParser, prefixParser and then compose them.
The main difference is that when building the prefixParser you don’t build it to parse the absence of prefix, just the actual prefix. Then you can combine them in prefixAndRestParser with something like |= prefixParser |. symbol (Token "?") |= restParser.

If we make a parallel to simple types in Elm, I’m suggesting that you avoid modelling your data with a type like this:

type alias MaybePrefix = Maybe Prefix
type alias Data = ( MaybePrefix, Rest )

and instead try modeling it like this:

type Data
  = WithPrefix ( Prefix, Rest )
  | WithoutPrefix Rest

This is because MaybePrefix does not makes sense on its own when in the Nothing variant. Only when the is a Rest afterward. This is basically trying to apply “making undesirable states unrepresentable” to parsing.

1 Like

I have been typing on my phone for these messages, so some responses are terse.

I was trying to parse a string like the following:

part1.part2.part3.part4
or
part2.part3.part4

I wanted to express optionally parsing part1. So, if I used oneOf without an “empty” parser, I would need to define something like parsePart2To4.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.