Skip to content

[#87] Amend Morley.Util.Named

Nikolay Yakimov requested to merge lierdakil/#87-amend-named-utils into master

Description

Problem: Using Morley.Util.Named interface introduced in !909 (merged) turns out to be inconvenient and frankly dangerous in practice. In no particular order, some issues:

  • (:!) and (:?) pattern synonyms can't be used with overloaded labels in the pattern context. The best we can do with those is

    (Name :: Name "label") :! value

    which is way more awkward then arg #label -> value

  • (:!) and (:?) can easily be abused by not providing the label either at the call site or in the pattern, e.g.

    someFunc (Name :! value)

    While this sometimes might be fine (e.g. when there's only one named argument), the potential for abuse is very strong.

  • N, M, SomeArg and NoArg pattern synonyms encourage eschewing label annotations entirely. Since those are bidirectional, they can be used also at call sites, which ultimately makes using named rather pointless.

Solution: Export arg, argF from Morley.Util.Named. Additionally, restrict the interface:

  • Deprecate N, M, SomeArg and NoArg. Suggest using 'arg' or 'argF' instead.

  • Do not export Name data constructor from Morley.Util.Named. This ensures it's not easy to abuse :! and :?.

  • For the rare case where Name needs to be used directly, export someName :: Name name, and add a couple HLint rules requiring the type annotation for someName.

  • Expand the documentation for :! and :? to make it clear(er) how those are intended to be used.

Note: It is still technically possible to eschew labels in patterns, e.g.

someFunc (_ :! value) = ...

While this can be abused, the hope is this looks suspicious enough to not get through review when the label is not immediately obvious from the surrounding context.

Related issue(s)

This is a follow-up to #87 (closed)

Checklist for your Merge Request

Related changes (conditional)

  • Tests (see short guidelines)

    • If I added new functionality, I added tests covering it.
    • If I fixed a bug, I added a regression test to prevent the bug from silently reappearing again.
  • Documentation

    • I checked whether I should update the docs and did so if necessary:
    • I updated changelog files of all affected packages released to Hackage if my changes are externally visible.

Stylistic guide (mandatory)

Edited by Nikolay Yakimov

Merge request reports