<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE message PUBLIC
  "-//MLarc//DTD MLarc output files//EN"
  "../../mlarc.dtd"[
  <!ATTLIST message
    listname CDATA #REQUIRED
    title CDATA #REQUIRED
  >
]>

  <?xml-stylesheet href="../../mlarc.xsl" type="text/xsl"?>


<message 
  url="2009/01/9921cb683ab06368e880d42f5319d6ce"
  from="Jacques Carette &lt;carette@m...&gt;"
  author="Jacques Carette"
  date="2009-01-20T16:44:26"
  subject="private types - suggestion"
  prev="2009/01/b3ffbc5aa0de84115687f2de96daa38e"
  next="2009/01/fa6c4452c1d8f79eeb50fa71a9e2e430"
  prev-thread="2009/01/362d9a24596895194833ad9dc424ca61"
  next-thread="2009/01/fa6c4452c1d8f79eeb50fa71a9e2e430"
  root="../../"
  period="month"
  listname="caml-list"
  title="Archives of the Caml mailing list">

<thread subject="private types - suggestion">
<msg 
  url="2009/01/9921cb683ab06368e880d42f5319d6ce"
  from="Jacques Carette &lt;carette@m...&gt;"
  author="Jacques Carette"
  date="2009-01-20T16:44:26"
  subject="private types - suggestion">
</msg>
</thread>

<contents>
[See full code below]

I have encountered a fairly subtle issue with private types which 
doesn't occur otherwise.  The source of the issue, I believe, is 
actually the need to have a 'row variable' available to be able to use 
'private' on a polymorphic variant.

In the code below (a massive simplification of my actual case), f 
compiles, but g does not, with error
Error: This pattern matches values of type
             [&gt; `Operator of 'a * 'b list * 'c S.pk ]
         but is here used to match values of types S.operator
        Types for tag `Operator are incompatible
(pointing to the line that starts with | `Operator ...)

First suggestion: could the error message please include what the 
incompatibility is? 
Second suggestion: could the type S.operator be (also) given in its 
'expanded' form?  It would be useful to know what the compiler thinks 
the type S.operator actually is.
Third suggestion: in this particular case, could the error message 
include some hints that the problem is one of [&lt; ] vs [&gt; ] ? [if my 
understanding of the issue is correct!]

I will add these suggestions to the bug system next, but I figured 
others on this list might benefit from my experience in debugging this 
issue in my code.

Jacques

PS: I actually don't want the intermediate type pk, po, pb and ps to be 
visible at all outside of S, but I do not know how to achieve that 
without adding another layer of indirection.  Any advice along these 
lines would be appreciated.

PPS: I experimented with variance annotations too, thinking that that 
might do the trick, but to no avail. 
---

module S : sig
    type 'a pk = KType | KFormula | Kind of 'a pb
    and  'a po = [`Operator of string * 'a pk list * 'a pk ]
    and  'a pb = [`Thing of string]
    type 'a ps = ['a po | 'a pb]

    type se = se ps
    type operator = private [&lt; se po]
end = struct
    type 'a pk = KType | KFormula | Kind of 'a pb
    and  'a po = [`Operator of string * 'a pk list * 'a pk ]
    and  'a pb = [`Thing of string]
    type 'a ps = ['a po | 'a pb]

    type se = se ps
    type operator = se po
end

open S

(* this one works *)
let f (o:operator) : string =
    match o with
    | `Operator(s, [], S.KType) -&gt; s
    | `Operator(_,_,_)          -&gt; failwith "nope"
(* this one doesn't ! *)
let g (o:operator) : string =
    match o with
    | `Operator(s, [], S.KType) -&gt; s
    | _                         -&gt; failwith "nope"
;;

</contents>

</message>

