Skip to content

In or-patterns, propagate path disambiguation from one prefixed constructor to other constructors #7386

@vicuna

Description

@vicuna

Original bug ID: 7386
Reporter: @gasche
Status: acknowledged (set by @xavierleroy on 2017-02-23T16:06:20Z)
Resolution: open
Priority: normal
Severity: feature
Version: 4.03.0
Category: typing
Related to: #5759 #5980 #7443
Child of: #6951 #7409
Monitored by: @ygrek @jmeber @yallop @hcarty

Bug description

If we write a record pattern or expression with fields { a; M.b; c }, it is understood as equivalent to { M.a; M.b; M.c }. I would like this property to also hold of variant constructors appear in an or-pattern (or at the head of a list of clauses): (A | M.B | C) should be equivalent to (M.A | M.B | M.C), and

  | A -> ...
  | M.B -> ...
  | C -> ...

equivalent to

  | M.A -> ...
  | M.B -> ...
  | M.C -> ...

Additional information

Here is a concrete example I just had of a situation where this feature would be useful to me:

  let fill_cache article_map =
    let open Canopy_content in
    let fold_fn key value acc =
      value () >>= fun content ->
      date_updated_created key >>= fun (updated, created) ->
      let uri = String.concat "/" key in
      match of_string ~uri ~content ~created ~updated with
      | Ok article ->
        article_map := KeyMap.add key article !article_map;
        Lwt.return acc
      | Error error ->
        let error_msg = Printf.sprintf "Error while parsing %s: %s" uri error in
        Lwt.return (error_msg::acc)
      | Unknown ->
        let error_msg = Printf.sprintf "%s : Unknown content type" uri in
        Lwt.return (error_msg::acc)
    in
    new_task () >>= fun t ->
    fold (t "Folding through values") fold_fn []

This is code is from https://github.com/Engil/Canopy . When compiled from 4.03, it raises the following warnings:

  File "canopy_store.ml", line 78, characters 4-716:
  Warning 45: this open statement shadows the constructor Ok (which is later used)
  File "canopy_store.ml", line 78, characters 4-716:
  Warning 45: this open statement shadows the constructor Error (which is later used)

The best way I see to silence the warning is to write

      match of_string ~uri ~content ~created ~updated with
      | Canopy_content.Ok article ->
        article_map := KeyMap.add key article !article_map;
        Lwt.return acc
      | Canopy_content.Error error ->
        let error_msg = Printf.sprintf "Error while parsing %s: %s" uri error in
        Lwt.return (error_msg::acc)
      | Unknown ->
        let error_msg = Printf.sprintf "%s : Unknown content type" uri in
        Lwt.return (error_msg::acc)

but I would find it natural if it was possible to prefix only the first constructor.

We previously discussed this feature during the type-based-constructor/field-disambiguation debate, but the applicability scope I had in mind was too broad and with an unclear specification. I believe that "are in a single or-pattern" (or, as a generalization, at the head of the clauses of a matching) is a clear, simple and useful specification.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions