Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006548OCamldocumentationpublic2014-09-09 18:362017-05-08 23:24
Reporterpveber 
Assigned Tooctachron 
PrioritynormalSeverityminorReproducibilityN/A
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product Version4.02.0+beta1 / +rc1 
Target VersionFixed in Version4.06.0+dev 
Summary0006548: Misleading comment on private type abbreviations
DescriptionIn "Language extensions", paragraph 7.9.2 says that

"For ambiguity reasons, typexpr cannot be an object or polymorphic variant type, but a similar behaviour can be obtained through private row types."

Actually private row types behave in a different way than what would be expected from private type abbreviation of a polymorphic variant:

# module T
  : sig type t = private [> `a | `b] end
  = struct type t = [`a | `b] end
;;
module T : sig type t = private [> `a | `b ] end
# let f (x : T.t) = match x with | `a -> true | `b -> false;;
Characters 18-57:
Warning 8: this pattern-matching is not exhaustive. Here is an example of a value that is not matched:
`AnyExtraTag
val f : T.t -> bool = <fun>

That is, exhaustivity check is not possible any more with private row types. The limitation of this workaround should be indicated, and other workarounds could be suggested:

- defining an auxiliary type:

module T
  : sig type t = private u and u = [ `a | `b] end
  = struct type t = [`a | `b] and u = t end;;

- using abstract types :

module T
  : sig type t val repr : t -> [`a | `b] end
  = struct type t = [`a | `b] let repr x = x end
;;

Tagsjunior_job
Attached Files

- Relationships
related to 0006589resolved Parameterized tag for manually specifying dependencies between modules 

-  Notes
(0012094)
lpw25 (developer)
2014-09-09 20:09

> "For ambiguity reasons, typexpr cannot be an object or polymorphic variant type, but a similar behaviour can be obtained through private row types."

This sentence should indeed be removed, but not for the reason suggested. It should be removed because this limitation was removed in version 4.02:

    # type t = private [ `A | `B ];;
    type t = private [ `A | `B ]

> Actually private row types behave in a different way than what would be expected from private type abbreviation of a polymorphic variant:
>
> # module T
> : sig type t = private [> `a | `b] end
> = struct type t = [`a | `b] end
> ;;
> module T : sig type t = private [> `a | `b ] end
> # let f (x : T.t) = match x with | `a -> true | `b -> false;;
> Characters 18-57:
> Warning 8: this pattern-matching is not exhaustive. Here is an example of a value that is not matched:
> `AnyExtraTag
> val f : T.t -> bool = <fun>

> That is, exhaustivity check is not possible any more with private row types.

This exhaustivity check is not failing because `t` is a private row type, it is failing because it is an *open* row type. I believe that you instead wanted a *closed* row type:

    type t = private [< `A | `B ];; (* Note < not > *)

Then the exhaustivity check passes as you wanted.

Also note that with a regular private type abbreviation you cannot match directly on the abbreviated type, but must instead use a coercion:

    # type t = private [ `A | `B ];;
    type t = private [ `A | `B ]

    # let f (x : t) = match x with `A -> 4 | _ -> 5;;
    Characters 29-31:
      let f (x : t) = match x with `A -> 4 | _ -> 5;;
                                   ^^
    Error: This pattern matches values of type [? `A ]
           but a pattern was expected which matches values of type t

    # let f (x : t) = match (x :> [ `A | `B ] ) with `A -> 4 | _ -> 5;;
    val f : t -> int = <fun>

So it is actually private type abbreviations that are more restricted than private row types.
(0012095)
pveber (reporter)
2014-09-09 20:44

Thanks a lot Leo for this explanation. It solves my initial problem well: I'll indeed use a private row type, but a closed one.

Also I'm glad I found a bug in the documentation, even if for a totally wrong reason ;o).
(0017784)
octachron (developer)
2017-05-08 23:24

The obsolete remark on the limitations of private type abbreviations was removed from the manual by integrating https://github.com/ocaml/ocaml/pull/1165 [^] .

- Issue History
Date Modified Username Field Change
2014-09-09 18:36 pveber New Issue
2014-09-09 20:09 lpw25 Note Added: 0012094
2014-09-09 20:44 pveber Note Added: 0012095
2014-09-14 21:36 doligez Status new => confirmed
2014-09-14 21:36 doligez Target Version => 4.03.0+dev / +beta1
2016-04-18 15:17 doligez Tag Attached: junior_job
2016-04-18 15:17 doligez Target Version 4.03.0+dev / +beta1 => 4.03.1+dev
2017-02-16 14:01 doligez Target Version 4.03.1+dev => undecided
2017-02-23 16:35 doligez Category OCaml documentation => Documentation
2017-02-23 16:44 doligez Category Documentation => documentation
2017-03-01 15:16 doligez Relationship added related to 0006589
2017-03-15 11:40 doligez Target Version undecided =>
2017-05-08 23:24 octachron Note Added: 0017784
2017-05-08 23:24 octachron Status confirmed => resolved
2017-05-08 23:24 octachron Fixed in Version => 4.06.0+dev
2017-05-08 23:24 octachron Resolution open => fixed
2017-05-08 23:24 octachron Assigned To => octachron


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker