2016-01-28 16 views
5

Buduję funkcję sortowania scalania, a moja metoda podziału daje mi błąd ograniczenia wartości. Używam 2 akumulujących parametrów, 2 listy wynikające z podziału, które pakuję do krotki na końcu dla powrotu. Jednak otrzymuję błąd związany z ograniczeniem wartości i nie mogę ustalić, na czym polega problem. Czy ktoś ma jakieś pomysły?F # Funkcja Split

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) 

Wszelkie dane wejściowe są mile widziane.

+0

prawo, a więc oczekuje się wejściowy będzie: Lista = [1, 2, 3, 4] oraz wyjście by następnie być, na przykład ([4, 2], [3, 1]) –

+0

Czy możesz sprawdzić informacje o tagach [F #] (http://stackoverflow.com/tags/f%23/info). –

Odpowiedz

10

Kod, jak już napisałeś, nie ma sensu. F # wykorzystuje wartości niezmienne domyślnie, więc swoją funkcję, jak to jest obecnie napisany, można uprościć do tego:

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

Prawdopodobnie nie jest to, co chcesz. W rzeczywistości, z powodu niezmiennych wiązań, nie ma żadnej wartości w predeclaringu a, b i ctr.

Oto funkcji rekurencyjnej, że załatwi:

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 

Zamiast korzystać z funkcji rekurencyjnej, można również rozwiązać ten problem za pomocą List.fold, fold jest funkcja wyższego rzędu które upowszechnia procesu akumulacji że opisaliśmy wyraźnie w powyższej funkcji rekursywnej.

Podejście to jest nieco bardziej zwięzłe, ale prawdopodobnie mniej znane nowemu programistycznemu, dlatego starałem się opisać ten proces bardziej szczegółowo.

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

Prosto na człowieka, który działał jak czar. Ciągle uczący się F # - nigdy wcześniej nie pracował z funkcjonalnym językiem. Pozdrawiam za pomoc! –