2017-09-30 7 views
0

Je suis en train de coder une fonction SML qui renvoie un tableau de résultats dans listViolations (L1, L2). Je veux spécifiquement faire une référence croisée entre chaque élément O (n^2), et vérifier si la sélection est en conflit les uns avec les autres. Visualiser: [[1, 2], [2, 3]] est l'option 1 et [[3, 2], [2, 1]] est l'option deux. Je qualifierais listViolations comme ceci: listViolations ([[[1, 2], [2, 3]], [[3, 2], [2, 1]]]).SML - Erreur: types de branches si ne sont pas d'accord

Le plan d'action serait de:

fun listViolations(L1, L2) = 
    if L1 = [] orelse L2 = [] 
     then 0 
    else totalViolations(transitive_closure(hd(L1)),path(hd(L2)))::[] @ listViolations(L1, tl(L2))::[] @ listViolations(tl(L1), L2)::[]; 

Ici je vérifie la tête des deux listes, et en passant sur les queues des deux récursive, dans l'espoir de créer quelque chose comme ceci: [3, 0 , 0].

Bien que je reçois cette erreur quand je déclare la fonction:

stdIn:726.5-728.136 Error: types of if branches do not agree [overload conflict] 
then branch: [int ty] 
else branch: int list 
in expression: 
    if (L1 = nil) orelse (L2 = nil) 
    then 0 
    else totalViolations (transitive_closure <exp>,path <exp>) :: 
     nil @ listViolations <exp> :: <exp> @ <exp> 

J'ai fourni toutes mes autres fonctions ci-dessous pour montrer qu'il n'y a rien de mal avec eux, je veux juste savoir s'il y a quelque chose im faire mal . Je sais pertinemment que

  • totalViolations (transitive_closure (hd (L1)), chemin (HD (L2)))
  • listViolations (L1, tl (L2)) :: []
  • listViolations (tl (L1), L2) :: [];

entiers de retour. Comment puis-je en faire une liste et la retourner dans cette fonction? Merci d'avance.

//[1, 2] , [1, 2, 3] = 0 
//[3, 2] , [1, 2, 3] = 1 
fun violation(T, P) = 
    if indexOf(hd(T), P) < indexOf(hd(tl(T)), P) then 0 
    else 1; 

//[[1, 2], [2, 3]] , [1, 2, 3] = 0 
//[[3, 2], [2, 1]] , [1, 2, 3] = 2 
fun totalViolations(TS, P) = 
    if TS = [] then 0 
    else violation(hd(TS), P) + totalViolations(tl(TS), P); 

//[[1, 2],[2, 3]] -> [1, 2, 3] 
fun path(L) = 
    if L = [] orelse L =[[]] 
     then [] 
    else union(hd(L),path(tl(L))); 

// [[1, 2],[2, 3]] -> [[1, 2],[2, 3], [1, 3]] 
fun transitive_closure(L) = union(L, remove([], closure(L, L))); 

Code additionnel:

fun len(L) = if (L=nil) then 0 else 1+length(tl(L)); 

fun remove(x, L) = 
    if L = [] then [] 
    else if x = hd(L) then remove(x, tl(L)) 
    else hd(L)::remove(x, tl(L)); 

fun transitive(L1, L2) = 
    if len(L1) = 2 andalso len(L2) = 2 andalso tl(L1) = hd(L2)::[] 
     then hd(L1)::tl(L2) 
    else []; 

fun closure(L1, L2) = 
    if (L1 = [[]] orelse L2 = [[]] orelse L1 = [] orelse L2 = []) 
     then [[]] 
    else if len(L1) = 1 andalso len(L2) = 1 
     then transitive(hd(L1), hd(L2))::[] 
    else 
     union(union(closure(tl(L1), L2), closure(L1, tl(L2))), transitive(hd(L1), hd(L2))::[]); 

Répondre

1

La branche then de votre if est un int tandis que la branche else est une liste de ints. Pour former une liste dans l'ancienne, écrire [0] (qui est juste court pour 0::[]). En outre, le résultat des appels récursifs dans l'autre branche est déjà prévu de retourner une liste, de sorte que le consing avec [] est faux, car il forme une liste de listes.

Plus de conseils: jamais comparer à la liste vide, cela forcera le type d'élément à être un type d'égalité. Utilisez plutôt le prédicat null. Mieux encore (et beaucoup plus lisible), éviter null, hd et tail tout à fait et utiliser la correspondance de motif.

+0

- listViolations fun (L1, L2) = = si L1 = [] orelse L2 = [] = alors [0] = else totalViolations (transitive_closure (hd (L1)), chemin (HD (L2))) :: [] @ listViolations (L1, tl (L2)) :: [] @ listViolations (tl (L1), L2) :: [] stdIn: 649.2-734.136 Erreur: du côté droit de la clause doesn ' t d'accord avec le type de résultat de la fonction [de non-concordance de Tycon] expression: int liste type de résultat: int dans la déclaration: listViolations = (fn (L1, L2) => si orelse puis :: autre : : ) De quoi aurais-je besoin pour obtenir la sortie désirée, une liste d'ints? –

+0

Supprime le ':: []' après les deux appels récursifs. –

+0

Je suis désolé, je me suis fatigué et j'ai toujours des erreurs. Pouvez-vous s'il vous plaît me montrer le code pour la version de travail? –