1

Dans Haskell, vous pouvez effectuer les opérations suivantes:types récursifs dans Mutually OCaml

Prelude> data Foo = Foo Bar; data Bar = Bar Foo 

Comment pouvez-vous faire la même chose en OCaml? J'ai essayé:

    ___ 
# type foo = Foo of bar;; type bar = Bar of foo;; 
Error: Unbound type constructor bar 

Est-il même possible de définir des types de données mutuellement récursifs dans OCaml? Si non alors pourquoi?

Comparer les définitions de données pour laisser des expressions: les types de données réciproquement réciproques correspondent à l'utilisation de let rec (ou mieux à type rec faute d'une meilleure expression). Quels sont les avantages de pouvoir définir des types de données mutuellement récursifs? Mon exemple de foobar est trivial. Pouvez-vous penser à des utilisations non triviales de types de données mutuellement récursifs?

Répondre

3

ivg répondu à votre question, mais voici un type non trivial mutuellement récursive.

module Stream = struct 

    type 'a t = unit -> 'a node 
    and 'a node = Nil 
       | Cons of 'a * 'a t 

end 

C'est le type réel de flux de la colonne vertébrale paresseux. Cela dit, vous pouvez construire sans les types mutuellement récursifs

type 'a t = Stream of (unit -> ('a * 'a t) option) 

Désinvolte ma pensée est que vous pouvez toujours réduire une famille de types mutuellement récursifs en un seul si vous voulez (mais peut-être pas OCaml l'encodage I Je pense à faire un usage non trivial des indices de type dépendants), mais il peut certainement être plus clair directement.

+1

en fait, votre deuxième définition de type ne fonctionne pas, il dira que la définition de type est cyclique. La méthode correcte serait 'type 'a t = Stream de (unité -> (' a * 'a t) option)' – ivg

+0

Oh, whoops! Ouais, n'a pas vérifié dans l'interprète. Fixé maintenant, merci. –

7

Utilisez and

type foo = Foo of bar 
and bar = Bar of foo 
+1

Récursivité réciproque explicite. J'aime ça plus que la syntaxe Haskell. Explicite est toujours mieux que implicite. –

+2

En fait, c'est légèrement moins qu'entièrement explicite. Ce qui serait au maximum explicite serait 'type rec foo = Foo de barre et barre = Bar de foo'. Vous rencontrez de (petits) problèmes quand, par exemple, il y a un type ambiant 't' et vous voulez faire un nouveau type' t' dans un sous-module qui alias l'ambiant 't', mais' type t module X = struct type t = t end' est une erreur car elle suppose que vous voulez construire le type infini 'type x = x'. –

+0

Il y a un intéressant plusieurs années [discussion] (http://caml.inria.fr/mantis/view.php?id=6623) sur ce sujet, qui aboutit à un nouveau mot-clé 'nonrec'. En 4.03, nous aurons 'type nonrec t' et même (je ne suis pas sûr si ça s'est retrouvé dans le patch final)' type rec t'. – ivg