To be clear, options aren't being handled differently from any other *pre-existing* user-defined type. utop # type 'a my_type = One of 'a | Two of 'a * 'a;; type 'a my_type = One of 'a | Two of 'a * 'a utop # type node = int * tree * tree and tree = node my_type;; Error: The type abbreviation node is cyclic Using a real ADT instead of a type abbrevation works. David Allsopp already gave one way you can do it, here is another which preserves the use of the option type: utop # type node = Node of int * tree * tree and tree = node option;; type node = Node of int * tree * tree and tree = node option Note that here [tree] is still a type abbreviation, but [node] is not, so the cycle is not a problem. Note also that your original example works fine with the -rectypes flag. But my general opinion is that if you need -rectypes to compile your code, you should write different code :) On 13 November 2015 at 22:24, Romain Bardou wrote: > On 13/11/2015 14:46, Romain Bardou wrote: > >> On 13/11/2015 14:37, David Allsopp wrote: >> >>> Mr. Herr wrote: >>> >>>> On 13.11.2015 13:49, Christoph Höger wrote: >>>> >>>>> Dear all, >>>>> >>>>> why is this type cyclic? >>>>> >>>>> type node = int * tree * tree >>>>> and tree = node option >>>>> >>>>> I cannot introduce a manifest for the option type, as there is no >>>>> Option module (why is that, btw?) - so I would assume option to be >>>>> special enough to be handled like any other algebraic data type. >>>>> >>>> type 'a option = None | Some 'a >>>> >>>> no need for a module, just a simple type. Maybe you confound it with >>>> other >>>> languages. >>>> >>>> And cyclic - well, the types are referring to each other. >>>> >>>> Summary: what is supposedly wrong with it? >>>> >>> >>> I expect that what is wrong is that you can write: >>> >>> type node = int * tree * tree >>> and tree = Some of node >>> | None >>> >>> I don't know why you can't write [and tree = node option] instead. >>> >>> >>> David >>> >>> >> Interestingly, this definition is accepted: >> >> type tree = (int * 'a * 'a) option as 'a >> >> Here you are helping the type-checker because you give it a "canonical" >> representation that it can use when unifying; it no longer has to expand >> the type, potentially infinitely. I think the main point is that the >> type is isorecursive, but I'm not really an expert on the subject. >> >> > My bad, I had actually redefined the option type as a polymorphic variant > before: > > type 'a option = [ `None | `Some of 'a ] > > and I forgot about it when I tested the definition of tree above. > > So yeah you can do that with polymorphic variants even though they are > kind of type abbreviations. > > Thanks to Daniel for pointing this out. > > -- > Romain > > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs >