2016-01-28 17 views
5

Birleştirme sıralama işlevi yapıyorum ve bölünmüş yöntemim bana bir değer kısıtlaması hatası veriyor. 2 biriktirme parametresi kullanıyorum, bölünmeden kaynaklanan 2 liste, dönüş için sonunda bir tuple paketliyorum. Ancak bir değer kısıtlaması hatası alıyorum ve sorunun ne olduğunu anlayamıyorum. Herhangi bir fikri olan var mı?F # Bölme İşlevi

let split lst = 
    let a = [] 
    let b = [] 
    let ctr = 0 
    let rec helper (lst,l1,l2,ctr) = 
     match lst with 
      | [] -> [] 
      | x::xs -> if ctr%2 = 0 then helper(xs, x::l1, l2, ctr+1) 
        else 
        helper(xs, l1, x::l2, ctr+1) 
    helper (lst, a, b, ctr) 
    (a,b) 

Herhangi bir girdi takdir edilir.

+0

Doğru, yani beklenen giriş olacaktır: liste = [1, 2, 3, 4] ve çıkış Daha sonra, işlem, örneğin, [(4; 2], [3; 1]) –

+0

mü [F # etiket bilgisi] 'ne göz atın (http://stackoverflow.com/tags/f%23/info). –

cevap

10

Yazdığınız gibi kod gerçekten anlam ifade etmiyor. F # Buna basitleştirilmiş olabilir, şu anda yazıldığı gibi, bu nedenle, varsayılan olarak işlev değişmez değerleri kullanır:

let split lst = 
    let a = [] 
    let b = [] 
    (a,b) 

İstediğin muhtemelen değil. Aslında nedeniyle değişmez bağları için, a, b ve ctr predeclaring hiçbir değer yoktur. İşte

hile yapacak özyinelemeli fonksiyonudur: Bir özyinelemeli fonksiyonu kullanımına

let split lst = 
    let rec helper lst l1 l2 ctr = 
     match lst with 
     | [] -> l1, l2 // return accumulated lists 
     | x::xs -> 
      if ctr%2 = 0 then 
       helper xs (x::l1) l2 (ctr+1) // prepend x to list 1 and increment 
      else 
       helper xs l1 (x::l2) (ctr+1) // prepend x to list 2 and increment 
    helper lst [] [] 0 

Bunun yerine, aynı zamanda fold birikim sürecini genelleştirir daha yüksek mertebeden fonksiyonudur, List.fold kullanarak bu sorunu çözmek verebilecek Yukarıdaki özyinelemede açıkça tanımladık.

Bu yaklaşım biraz daha özlü fakat işlevsel programlamada yeni birisine daha az aşina olduğu için, bu süreci daha ayrıntılı olarak açıklamaya çalıştım.

let split2 lst = 
    /// Take a running total of each list and a index*value and return a new 
    /// pair of lists with the supplied value prepended to the correct list 
    let splitFolder (l1, l2) (i, x) = 
     match i % 2 = 0 with 
     |true -> x :: l1, l2 // return list 1 with x prepended and list2 
     |false -> l1, x :: l2 // return list 1 and list 2 with x prepended 
    lst 
    |> List.mapi (fun i x -> i, x) // map list of values to list of index*values 
    |> List.fold (splitFolder) ([],[]) // fold over the list using the splitFolder function 
+2

İnsan üzerinde, bu bir cazibe gibi çalıştı. Hala F # öğrenme - daha önce işlevsel bir dil ile hiç çalışmadı. Yardım için şerefe! –