2017-10-03 6 views
0

Pardonnez ma nouveauté à OCaml, mais j'ai une fonction très simple où je retourne l'intersection de deux listes, mais seulement quand l'élément est dans les deux listes en même temps. Sur la troisième ligne, on me dit "Cette expression a un type 'mais une expression était attendue de type' une liste ', mais n'est-ce pas une liste que je produis?Pourquoi n'est-ce pas une liste?

let rec intersection (l1 : 'a list) (l2 : 'a list) : 'a list = match l1,l2 with 
    | [],[] -> []    (* empty lists *) 
    | [h1::t1], [h2::t2] -> (* non-empty lists *) 
     if h1 = h2   (* if both elements are the same *) 
     then h1 :: intersection(t1,t2) (* include in intersection response *) 
     else intersection(t1, t2)  (* else ignore it and check the remaining elements *) 
+0

Tous les bras doivent retourner le même type. Dans l'expression 'else', il me semble' intersection (t1, t2) 'peut renvoyer juste un' 'a'. L'affichage de l'intégralité de la fonction serait plus utile. – PieOhPah

+2

'intersection (t1, t2)' appelle 'intersection' avec un tuple' (t1, t2) '. Il devrait être appelé 'intersection t1 t2'. – PieOhPah

+0

Ne semble pas changer quoi que ce soit avec l'erreur de type. Toujours obtenir Cette expression a le type 'a mais une expression était attendue de type ' une liste La variable de type 'a se produit dans' une liste – Swift142

Répondre

1

L'expression a :: b est une liste dont la tête est a et dont la queue est b. Ainsi, l'expression [a :: b] est une liste de listes. Très probablement vos modèles devraient être h1 :: t1 et h2 :: t2.

Il serait beaucoup plus facile de vous aider si vous postez toute la fonction comme le signale @PieOhPah.

Mise à jour

Il y a au moins deux erreurs dans votre code. Si je compile votre code comme indiqué ci-dessus, je vois ceci:

File "a1.ml", line 5, characters 13-15: 
Error: This expression has type 'a but an expression was expected of type 
    'a list 
    The type variable 'a occurs inside 'a list 

Si je change votre modèle [h1 :: t1], [h2 :: t2]-h1 :: t1, h2 :: t2, je vois ceci:

File "a2.ml", line 5, characters 31-38: 
Error: This expression has type 'b * 'c 
    but an expression was expected of type 'a list 

Cette deuxième erreur se produit parce que vos appels récursifs à intersection passent des tuples intersection (a, b). Mais intersection est défini sous forme curryte, c'est-à-dire qu'il prend des arguments séparés intersection a b. C'est ce que @PieOhPah signale.

Si j'apporte les deux modifications, je ne vois aucune autre erreur de type. Il y a d'autres erreurs, mais ce ne sont pas des erreurs de type.

+0

ajouté la fonction entière. OCaml ne permet-il pas de définir des listes entre parenthèses sans qu'il s'agisse d'une liste de listes? – Swift142

+2

Il existe deux notations pour les listes: '[a; b] 'et' a :: b :: [] '. Vous avez combiné ces notations, vous obtenez ainsi une liste de listes. –

+0

@JeffreyScofield réponse est assez claire. Le contre ('::') construit déjà une liste. Cela signifie que vous devriez faire correspondre '(h1 :: t1, h2 :: t2)' sans crochets (parenthèses uniquement pour plus de clarté). – PieOhPah