Problème de typage en Caml

Le problème exposé dans ce sujet a été résolu.

Bonjour.

Je suis un gros débutant en programmation fonctionnelle, et en Ocaml, et actuellement j’essaye d’écrire des fonctions qui parcours une structure de donnée faite d’enregistrement, et qui renvoie la traduction en json tel que je l’ai voulu.

J’utilise Yojson.

Les types que j’utilise :

1
2
3
4
5
6
7
8
9
type json = [
  | `Assoc of (string * json) list
  | `Bool of bool
  | `Float of float
  | `Int of int
  | `List of json list
  | `Null
  | `String of string
]

et les deux fonctions qui posent problèmes

1
2
3
4
5
6
7
8
9
let rec parse_object obj = match obj with
    |[] -> `Assoc[] :: []
    |[{name = l; aspects = d; role = r}] -> `Assoc[("name",`String l);
                                                    ("role",`String "Empty");
                                                    ("aspects",(parse_aspect d))] :: []

    |head::queue -> `Assoc[("name",`String head.name);
                            ("role",`String "Empty");
                            ("aspects",(parse_aspect head.aspects))] :: parse_object queue
1
2
3
4
5
6
7
8
9
let rec parse_aspect asp = match asp with
    |[] -> `Assoc [] :: []
    |[(app,asp,obj)] -> `Assoc[("application_type",`String (application_to_string app));
                                ("aspect_type",`String (aspect_to_string asp));
                                ("target",`String obj.name)] :: []

    |(app,asp,obj)::queue -> `Assoc[("application_type",`String (application_to_string app));
                            ("aspect_type",`String (aspect_to_string asp));
                            ("aspects",`String obj.name)] :: parse_aspect queue

Mon problème :

La fonction parse_object m’embête sur le type du tableau « Assoc » vu que les deux premiers éléments c’est du « (string, String of string)» Et que moi le 3eme élément je récupère autre chose via la fonction parse_aspect, typé comme 3 tuple de « (string, `String of string)» donc logiquement le compilateur me sort

This expression has type [> Assoc of (string * [> String of string ]) list ] list but an expression was expected of type [> String of string ]

Mais moi je peut pas faire autrement, c’est pas possible de devoir se contraindre a avoir des objets json qui ont a chaque fois le même type dans chaque champ.

Et bizarrement quand j’ai fait un petit test d’affectation, bah il m’emmerde pas sur le type du tableau Assoc alors que je mélange différent tuple de différent type.

1
2
3
let test = `List[`Assoc[("lol",`String "lel") ; 
                        ("loli",`String "lel"); 
                        ("lola",`List [ `Assoc[("hey",`String "lel")] ; `Assoc[("hay",`String "lel")] ]) ]]

ça bah ça compile et ça marche, dans un seul objet json j’ai 3 champs qui sortent des types différents

1
2
3
4
5
6
7
8
9
{
    "lol": "lel",
    "loli": "lel",
    "lola": [{
        "hey": "lel"
    }, {
        "hay": "lel"
    }]
}

du coup comment je peut regler ce problème de typage sur ma fonction parse_object ?

Merci.

Bonjour,

D’abord première remarque : dans tes deux fonctions récursives ton cas ligne 3 n’est pas nécessaire puisqu’il est inclus dans celui dans la ligne 7.

1
2
3
4
let rec f a = match a with
 | [] -> ...
 | [b] -> ... // revient à head::[] donc inclus dans le 3ème cas.
 | head::queue -> ...

Autrement, ton problème est que la fonction parse_aspect renvoie une liste de json alors que la fonction parse_object attends juste un élément de l’énumaration json.

Cela ne corresponds pas au cas tu décris ensuite, cela serait plutôt quelque chose comme :

1
`List[`Bool(false); `Int(4); [`Bool(false)]] // 3ème membre est une list qui n'est pas reconnue par l'énumération du type json

Je pense (mais je ne suis pas sûr) que pour régler cela il faut utiliser la `List, et dans la fonction parse_object on a alors :

1
("aspects", `List(parse_aspect head.aspects))] :: parse_object queue

plutôt que

1
("aspects", (parse_aspect head.aspects))] :: parse_object queue
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte