• # Ouh là

    Posté par (site web personnel) . En réponse au message [OCaml] Typage complexe et type "Block". Évalué à 3.

    Bon, allons y doucement :)

    Tout d'abord, ton souci de compilation est dû au fait que OCaml n'aime pas mélanger les classes et et les types. De manière générale, évite les classes si tu n'utilises pas l'héritage, et utilise plutôt les record. De cette manière, tu pourrais écrire:

    type agent = 
     {
     mutable startState : state 
     }
    and transition = Condition of (agent -> bool) 
     | Event of (agent -> bool) 
     | ConditionOr of (agent -> bool) 
     | ConditionAnd of (agent -> bool) 
     | ConditionXor of (agent -> bool) 
     | ConditionNor of (agent -> bool)
    and state = 
     {
     mutable parentstate : state option;
     mutable substate : state option;
     mutable transitions : state list;
     mutable begin_action : state -> state;
     mutable action : state -> state;
     mutable end_action : state -> state
     }
    Note que je ne suis pas tout à fait sûr de tes types pour state, j'ai mis ce qui me paraissait logique. Le type option de la bibliothèque standard remplace avantageusement ton stateOuRien.

    J'espère que cela répond également à la question subsidiaire: quand bien même l'on peut gérer la plupart de ses types implicitement, il est pratique de définir tout d'abord ce sur quoi on travaille, à l'aide de records et de variants. Il est ensuite possible par exemple de forcer un type dans une fonction, par exemple:

    let run_state (a:state) = a
    sera typée comme fun : state -> state au lieu du générique fun : a ->a. Cela peut notamment rendre les messages d'erreur plus explicites et moins ésotériques.

    Pour la question 2, je sèche, je ne comprends pas ce qu'est un type bloc (je suis un programmeur un peu old school :) ). Si tu as un record, tu peux le modifier directement:

    let a =
     {
     parentstate = None;
     substate = None;
     transitions = [];
     begin_action = (fun e -> e);
     action = (fun e -> e);
     end_action = (fun e -> e)
     };;
    a.transitions <- [a];;
    C'est autre chose que tu cherches?

    De manière générale, pour s'en sortir en Ocaml, mieux vaut une approche bottom-up:

    • Créer les types dont on a besoin, à partir de records et de variants, en tentant de les garder aussi non-mutables que possible, et laisser de côté l'objet tant qu'on est sûr de ne pas en avoir besoin
    • Construire les fonctions qui vont travailler sur ces types, en partant du plus basique, et en testant souvent
    • Augmenter la complexité en écrivant des fonctions de plus haut niveau, s'appuyant sur les plus basses.

    Bonne chance!