早期退出/停止Array2D.initBased

时间:2014-02-20 21:16:42

标签: arrays f# exit break

如何在F#中提前退出/中断/停止数组创建(在本例中为Array2D.initBased)?

备注: dicDictionary<,>(),其值是一个对象,其方法名为someMethod,需要两个int参数。< / p>

let arr = Array2D.initBased 1 1 width height (fun x y -> 
    let distinctValues = dic |> Seq.map (fun (KeyValue(k,v)) -> v.someMethod x y) |> Set.ofSeq
        match distinctValues.count with
        | dic.Count ->
            // do something
            // exit array creation here, because I do not need arr any more if v.someMethod x y produced distinct values for each dic value
        | _ -> 
            // do something else

1 个答案:

答案 0 :(得分:2)

这是一个棘手的问题 - 我认为没有任何功能可以让你轻松地做到这一点。我认为最好的选择可能是定义你自己的高阶函数(使用非常优雅的递归实现)来隐藏行为。

这个想法是定义行为为tryInitBased的{​​{1}},但用户提供的函数可以返回选项(表示失败),函数返回选项(成功创建数组或{{1 }}):

initBased

然后,您可以保持代码几乎相同,但将None替换为/// Attempts to initialize a 2D array using the specified base offsets and lengths. /// The provided function can return 'None' to indicate a failure - if the initializer /// fails for any of the location inside the array, the construction is stopped and /// the function returns 'None'. let tryInitBased base1 base2 length1 length2 f = let arr = Array2D.createBased base1 base2 length1 length2 (Unchecked.defaultof<_>) /// Recursive function that fills a specified 'x' line /// (returns false as soon as any call to 'f' fails, or true) let rec fillY x y = if y < (base2+length2) then match f x y with | Some v -> arr.[x, y] <- v fillY x (y + 1) | _ -> false else true /// Recursive function that iterates over all 'x' positions /// and calls 'fillY' to fill individual lines let rec fillX x = if x < (base1+length1) then if fillY x base2 then fillX (x + 1) else false else true if fillX base1 then Some arr else None 并从lambda函数返回initBasedtryInitBased

我还将功能发布到F# snippets,格式更精确。