2010-06-15 14 views
7

Listeye bakıp bir çift sayı döndüren basit bir özyinelemeli fonksiyon yazmaya çalışıyorum. .. bu yüzdenocaml pattern match question

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) 

sorun Bu c/C++/java yazmak kolaydır ama eski çatışma olması gerektiği

böyle gider tip nedeniyle çözüm bulmak çok nasılsa zor ocaml yeniyim tuple'daki değeri nasıl döndürebilirim ..

+2

Bu işlevin ne için döndürüleceği ile ilgili daha fazla bilgi verebilir misiniz? Tam sayı çifti neyi temsil ediyor? – goggin13

+0

bu yüzden bir çift tamsayı (x, y) ochl içinde tuple olarak döndürmelidir, sadece karşılaştığım problemin bir tuple hesaplaması olduğunu .. böylece bir liste daha sonra bir sayıdan azsa (x +1, y) else (x, y + 1) böylece dönüş değeri (x, y) olacaktır, burada x, bir sayıdan büyük olan elemanların sayısıdır ve y, – REALFREE

cevap

4

biraz OCaml uzak mu, but I için başlığın parçaları çekmeyi iç içe maç ifadesi kullanan bu yorumun

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);; 

yılında REALFREE açıklamasında açısından hile olacaktır düşünüyorum değiştirmek

DÜZENLEME:

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);; 
: Ben Pascal Cuoq aşağıda onun yorumunda belirtilen sözdizimi hakkında bilmiyordum , burada böyle kod neater var ve biraz daha kısa, var

Ancak kabul edilen cevap, özellikle kuyruk özlemi ile daha iyi, daha iyidir;).

+2

ve eğer bir eşleme ile bir eşleşme .. 'yazıyorsanız,' let' yerine şunu kullanabilirsiniz: 'x, y = xs yi test et… –

5

Buradaki bir sorun, iki farklı türde döndüğünüzdür: boş bir liste için int veya aksi halde bir grup. Biri diğeri olmalı.

Başka bir sorun, 1 ile test eklemeye çalıştığınız, ancak test bir işlev değil, bir değerdir. Bir değer döndürmek için başka bir şey üzerinde test çağırmanız gerekir, ancak daha sonra bir tam sayıya eklenemeyen bir tuple döndürmesi gerekir.

Kodun ne yapmasını istediğinizi anlayamıyorum, ancak sorunuzu bu bilgilerle güncelleştirirseniz daha fazla yardımcı olabilirim.

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

Güncelleme: Ben

Bir tahminim böyle yazabilirim bu durumda listede pozitif sayılar, saymak istiyor olmasıdır sen netleştirmek için düzenlenmiş beri

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;; 

akümülatörler bu durumda çok yardımcı kullanarak şu şekildedir: sorun, yukarıdaki kodunu değiştirin. Aynı zamanda, her zaman iyi bir uygulama olan kuyruk özyinelemesini yapar.

+0

'dan daha azdır. ? – REALFREE