| Anonymous | Login | Signup for a new account | 2013-05-19 16:20 CEST | ![]() |
| Main | My View | View Issues | Change Log | Roadmap |
| View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||||
| ID | Project | Category | View Status | Date Submitted | Last Update | ||||||
| 0004998 | OCaml | OCaml general | public | 2010-03-10 16:45 | 2011-06-01 17:06 | ||||||
| Reporter | goswin | ||||||||||
| Assigned To | |||||||||||
| Priority | normal | Severity | feature | Reproducibility | always | ||||||
| Status | acknowledged | Resolution | open | ||||||||
| Platform | OS | OS Version | |||||||||
| Product Version | |||||||||||
| Target Version | Fixed in Version | ||||||||||
| Summary | 0004998: Feature request: Sub/Supersets of non-polymorphic variants | ||||||||||
| Description | I find myself in a position where I have to store number of items in a tree structure. So I defined a variant type covering all the items. In other places of the code, where I use the items, I know that only a limited set of items can ever occur or must only occur. Other items can or may not occur. With a non-polymorphic variant type I have no way to reflecting that fact in the type of values and then I need to match cases I know can/must not happen or suffer lots of warnings. On the other hand polymorphic variants use more memory and my tree will be HUGE so that is a real concern. Polymorphic variants also require type annotations to close the type and to get the strict typechecks like non-polymorphic variants. Consider the following polymorphic variant: # type 'a t = 'a constraint 'a = [ `A | `B | `C ];; type 'a t = 'a constraint 'a = [ `A | `B | `C ] # let f = function `A -> `B | (x : [< 'a t]) -> x;; val f : ([< [ `A | `B | `C ] t > `B ] as 'a) -> 'a = <fun> # let x = (`A : [`A | `B]);; val x : [ `A | `B ] = `A # let y = match f x with `A -> "A" | `B -> "B";; val y : string = "B" # let z = match x with `A -> "A";; Error: This pattern matches values of type [< `A ] but a pattern was expected which matches values of type [ `A | `B ] The first variant type does not allow tag(s) `B And now contrast that with the non-polymorphic type # type t = A | B | C;; type t = A | B | C # let f = function A -> B | x -> x;; val f : t -> t = <fun> # let x = A;; val x : t = A # let y = match f x with A -> "A" | B -> "B";; Warning P: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: C val y : string = "B" # let z = match x with A -> "A";; Warning P: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: (C|B) val z : string = "A" Wouldn't it be great if one could declare a subset of the variant type: let x = (A : [A | B]);; Then the warning for y could be avoided as the type system would know that C will never happen. Also for z it could produce an error same as for the polymorphic variant example. I do not ask for the existing behaviour of non-polymorphic variants to change. The sub/supersets should only be given explicitly and not infered like polymorphic variants. So example below should still give that warning unlike g. # let f = function A -> "A" | B -> "B";; Warning P: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: C val f : t -> string = <fun> # let g = function `A -> "A" | `B -> "B";; val g : [< `A | `B ] -> string = <fun> Also non-polymorphic variants would always be limited to be a subset of the full type. One could not write: # type s = D let f = function A -> "A" | B -> "B" | C -> "C" | D -> "D";; Error: This pattern matches values of type s but a pattern was expected which matches values of type t MfG Goswin | ||||||||||
| Tags | No tags attached. | ||||||||||
| Attached Files | |||||||||||
Issue History |
|||
| Date Modified | Username | Field | Change |
| 2010-03-10 16:45 | goswin | New Issue | |
| 2011-06-01 17:06 | doligez | Note Added: 0005950 | |
| 2011-06-01 17:06 | doligez | Status | new => acknowledged |
| Copyright © 2000 - 2011 MantisBT Group |