2017-01-09 114 views
2

以下代碼找到maxLen給出的值列表。 maxLen是一個可變值。如何刪除它更多的功能練習?如何刪除代碼中的全局可變變量?

let reject pos = // reject a given pos, the implementation is contrived 
    let s = [4; 9; 14] // Just an example, any value may be rejected 
    s |> List.exists (fun x -> x = pos) 

let getLength pos = if pos % 3 = 0 then pos * 2 else pos 

let mutable maxLen = 0 

let getNewPosAndSetMaxLength pos len = // For each new position, check if the result of `getLenth pos` is larger than previous ones. 
    let direction = if len < 1 then -1 else 1 
    let newPos = 
     match [1..abs(len)] |> List.tryFind (fun i -> reject (pos + i * direction)) with 
     | Some p -> p 
     | None -> pos + len 
    let newLen = getLength newPos 
    maxLen <- if newLen > maxLen then newLen else maxLen 
    newPos 

[<EntryPoint>] 
let main argv = 
    let pos = 0 
    [3; -2; 6; 7] 
    |> List.iter (fun x -> 
     let pos = getNewPosAndSetMaxLength pos x 
     () 
    ) 
    printfn "%d" maxLen 
    0 // return an integer exit code 
+0

您是否嘗試過使用''而不是''名單List.fold'' .iter''和可變? – Gustavo

+0

謝謝,我想我需要改變函數'getNewPosAndSetMaxLength'來返回newPos和length。 – ca9163d9

回答

2

如果更改getNewPostAndSetMaxLength採取當前的最大長度,並返回一對(pos, maxLength)您可以使用List.fold

let getNewPosAndSetMaxLength maxLen pos len = // For each new position, check if the result of `getLenth pos` is larger than previous ones. 
    let direction = if len < 1 then -1 else 1 
    let newPos = 
     match [1..abs(len)] |> List.tryFind (fun i -> reject (pos + i * direction)) with 
     | Some p -> p 
     | None -> pos + len 
    let newLen = getLength newPos 
    let maxLen' = if newLen > maxLen then newLen else maxLen 
    (newPos, maxLen') 

[<EntryPoint>] 
let main argv = 
    let (lastPos, maxLen) = [3; -2; 6; 7] |> List.fold (fun (pos, maxLen) x -> 
     getNewPosAndSetMaxLength maxLen pos x) (0, 0) 
    printfn "%d" maxLen 
    0 // return an integer exit code