2010-06-15 12 views
7

J'essaie d'écrire une fonction récursive simple qui regarde la liste et renvoie une paire d'entiers. Cela est facile à écrire en c/C++/java mais je suis nouveau à ocaml donc en quelque sorte difficile de trouver la solution en raison de conflits de typeocaml pattern match question

il se doit .. va comme

let rec test p l = ... ;; 
val separate : (’a -> bool) -> ’a list -> int * int = <fun> 
test (fun x -> x mod 2 = 0) [-3; 5; 2; -6];; 
- : int * int = (2, 2) 

donc le problème est comment puis-je retourner récursivement la valeur sur tuple ..

+2

Pourriez-vous fournir plus de détails sur ce que cette fonction est censée renvoyer? Que représente la paire d'entiers? – goggin13

+0

donc il devrait retourner une paire de nombres entiers comme (x, y) qui est tuple dans ocaml que seul le problème que j'ai rencontré est le calcul de tuple .. donc c'est comme si un élément de liste est moins alors un certain nombre (x +1, y) else (x, y + 1) donc la valeur de retour sera (x, y) où x est le nombre d'éléments qui est supérieur à un certain nombre et y est inférieur à – REALFREE

Répondre

4

été loin de OCaml pour un peu, mais je pense que cela fera l'affaire en ce qui concerne la description de REALFREE dans le commentaire

let rec test l = 
    match l with 
     [] -> (0,0) 
    | x::xs -> 
     if x > 0 then match (test xs) with (x,y) -> (x+1, y) 
     else match (test xs) with (x,y) -> (x, y+1);; 

Vous pouvez utiliser les instructions de match imbriquées pour tirer des morceaux du tuple modifier

EDIT: Je ne savais pas sur la syntaxe Pascal Cuoq a mentionné dans son commentaire ci-dessous, voici le code comme ça, il est plus propre et un peu plus court:

let rec test l = 
    match l with 
     [] -> (0,0) 
    | x::xs -> 
    if x > 0 then let (x,y) = test xs in (x+1, y) 
    else let (x,y) = test xs in (x, y+1);; 

Mais la réponse acceptée est encore beaucoup mieux, surtout avec la récursivité de la queue;).

+2

et si vous écrivez un 'match .. avec .. 'avec un seul motif, vous pouvez utiliser' let' à la place: 'soit x, y = test xs dans ...' –

5

Un problème ici est que vous retournez deux types différents: un int pour une liste vide, ou un tuple autrement. Il doit être l'un ou l'autre.

Un autre problème est que vous essayez d'ajouter 1 à test, mais test est une fonction, pas une valeur. Vous devez appeler test sur autre chose pour qu'il renvoie une valeur, mais même dans ce cas, il est supposé retourner un tuple, que vous ne pouvez pas ajouter à un entier.

Je n'arrive pas à comprendre ce que vous voulez que le code fasse, mais si vous mettez à jour votre question avec cette information, je peux vous aider davantage.

Une supposition que j'ai est que vous voulez compter les nombres positifs dans la liste, dans ce cas, vous pouvez l'écrire comme ceci:

let rec test l = 
    match l with [] -> 0 
    | x::xs -> if x > 0 then 1 + (test xs) 
       else test xs;; 

Mise à jour: puisque vous avez modifié pour clarifier le problème, modifiez le code ci-dessus comme suit:

let test l = 
    let rec test_helper l pos nonpos = 
    match l with [] -> (pos, nonpos) 
    | x::xs -> if x > 0 then test_helper xs 1+pos, nonpos 
       else test_helper xs pos 1+nonpos 
    in test_helper l 0 0;; 

L'utilisation des accumulateurs aide beaucoup dans ce cas. Cela rend également la fonction récursive à la queue, ce qui est toujours une bonne pratique.

+0

comment puis-je le modifier pour transférer récursif ? – REALFREE