> Similarly, you cannot do this
> type t = A of {l1:int}
> | B of {l2:float}
> | C of {l1:int; l2:float}
You can do that with object types:
type t =
| A of < l1 : int >
| B of < l2 : float >
| C of < l1 : int; l2 : float >
Similarly, polymorphic variants are structural counterparts of variant types.
# if true then `Foo (object method l1 = 1 end) else `Bar (object
method l1 = 2 method l2 = 2. end);;
- : [> `Bar of < l1 : int; l2 : float > | `Foo of < l1 : int > ] = `Foo <obj>
Those types are more complex to use that named variant and structures,
tend to generate hard-to-read error messages (unless you carefully
annotate your code to avoid having too many unknowns in the exact type
used), and are slightly less efficient at runtime. Flexibility comes
at a price.
Most Ocaml programmers actually favor plain, simple language
constructs. Objects and polymorphic variants are used when their
flexibility is clearly required by the application, which is actually
not very often. You can learn more about objects in the OCaml manual,
and about polymorphic variant in Jacques Garrigue's article "Code
reuse through polymorphic variants":
- http://caml.inria.fr/pub/docs/manual-ocaml/manual005.html
- http://www.math.nagoya-u.ac.jp/~garrigue/papers/fose2000.html
On Sun, Oct 16, 2011 at 10:24 PM, Matej Košík <[email protected]> wrote:
> On 10/16/2011 09:24 PM, Gabriel Scherer wrote:
>> If record were structurally typed, there would be an ambiguity as to,
>> for example, what this function mean:
>>
>> let access_foo t = t.foo
>>
>> What would the type of `access_foo` be ? { foo : 'a } -> 'a ? { foo :
>> 'a; bar : 'b } -> 'a ?
>
> { foo : 'a } -> 'a
>
> seems plasible
>
>> Should `access_foo { foo = 1 }` be typable? And `access_foo { foo = 1;
>> bar = true }` ?
>>
>> In this situation, you want record subtyping. This get more
>> complicated than the relatively simple OCaml records.
>
> This may be too troublesome to support but I guess it is plausible language
> change and it would enable additional Ocaml terseness. Let me clarify.
>
> At the moment, it is not possible to do this:
>
> type t = {l1:int} * {l2:int};;
>
> It is a syntax error. We are forced to do it gradually:
>
> type t1 = { l1 : int; }
> type t2 = { l2 : int; }
> type t = t1 * t
>
> This is somewhat cumbersome.
>
> Similarly, you cannot do this
>
> type t = A of {l1:int}
> | B of {l2:float}
> | C of {l1:int; l2:float}
>
> Only this works:
>
> type t1 = { l1 : int}
> type t2 = { l2 : float}
> type t3 = { l1 : int; l2: float}
> type t = A of t1
> | B of t2
> | C of t3
>
> We were forced to introduce three superfluous type-names [t1;t2;t3].
> How would you feel if you were forced to do that for every tuple-type?
>
> Sometimes tuples are not ideal
> (when they have lots of members)
> Records are better in those cases because you can access elements by their
> label and when you construct records with lots of fields, the labels clarify
> which field has what meaning. But switching from tuples to records is not
> smooth. What could be gained in readability (labeled fields) is lost by
> cluttering the program by auxiliary record type definitions.
>
>> In fact, OCaml
>> has structurally typed structures with named fields : objects
>>
>> # let access_foo t = t#foo;;
>> val access_foo : < foo : 'a; .. > -> 'a = <fun>
>> # access_foo (object method foo = 1 method bar = true end);;
>> - : int = 1
>
> Interesting.
>
>>
>> Tuples don't have this issue as they don't have an universal accessor
>> function : there is no way to get the first element of a tuple
>> whatever its width is. Therefore, all tuples manipulation make the
>> structure concrete, and structural subtyping comes at no complexity
>> cost ... if you accept the absence of universal accessors. SML has
>> them (#1 #2 etc.) and I'm not sure how they handle this.
>
> --
> Matej Košík
>
> --
> Caml-list mailing list. Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>
--
Caml-list mailing list. Subscription management and archives:
https://sympa-roc.inria.fr/wws/info/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs