natefaubion / purescript-routing-duplex

Unified parsing and printing for routes in PureScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"Non ending" version of `sum`

paluh opened this issue · comments

commented

I'm using "non ending" version of Generic.sum to encode / decode parts of the routes into sums. Currently I have a copy of the whole GRouteDuplex class without this end call and it works fine.

Do you think it could be valuable addition to this lib to provide a sum version which covers such a scenario (of course with better implementation than what I'm using internally now ;-))?

What use case does a non-ending sum solve for you?

The reason that we use end is that the ordering of the alternative is "basically" undefined. I can't ever remember if it's lexicographical, the ordering of the data declaration, or something else. If you don't check for end and you do something like:

routes = G.sum
  { "A": "foo" / noArgs
  , "B": "foo" / "bar" / noArgs
  }

Then B may never parse. I'm very hesitant to add a non-ending variation of this using the record literal syntax without a compelling use case.

commented

What use case does a non-ending sum solve for you?

Maybe I'm abusing this library but I've found it really powerful and started to encode more and more sophisticated types with it. So for example I'm encoding "inner sums values" like the DesignId in this Route below:

data SvgRender
  = Grid Tessellation.Grid
  | ViewPort ...

data DesignId
  = DebugGrid DebugGrid
  | DesignId String Instant

data Route
  = Svg DesignId SvgRender
  | Bitmap DesignId BitmapRender
  ...

The reason that we use end is that the ordering of the alternative is "basically" undefined.

To be honest as a user I assumed that there is no backtracking here and I use distinguishing prefixes all the time :-)

I'm very hesitant to add a non-ending variation of this using the record literal syntax without a compelling use case.

I fully understand your point. I can stick with my internal copy of the typeclass - no problem :-)

Should I close this?

Maybe the solution to that is an ordered DSL, like record?

G.trySum
  # G.constructor (SProxy :: _ "B") ("foo" / "bar" / noArgs)
  # G.constructor (SProxy :: _ "A") ("foo" / noArgs)

It's not as fancy as a record literal, but it makes the ordering explicit.

I agree that using something like sum for individual pieces (that aren't necessarily at an end) would be nice. I'd like to think about what all the options are.

Another solution to consider is removing the end, and documenting that backtracking may require usage of end to disambiguate branches. I know that's me backtracking on my reasoning, but I can also see that being desirable.