F# 所使用的是 Monadic 组合子(Computation Expression 的一种),这是一种方便的方法,可以组合代码,并使其看起来更复杂。然而,如果使用嵌套组合子的次数过多,就会出现'too many calls to nested Computation Expression”的错误。
解决此问题的一个方法是,将嵌套组合子的代码拆分成单独的函数,然后在组合成一个整体。这样做可以减少嵌套组合子的次数。以下是一个示例代码,使用 MonadBuilder 组合两个 List,然后使用另一个组合子将结果排序:
open System.Collections.Generic
type MonadBuilder () =
member this.Bind(x, f) = List.collect f x
member this.Return(x) = [x]
member this.ReturnFrom(x) = x
member this.Delay(f) = f ()
let monad = MonadBuilder()
let combineLists (list1 : 'a list) (list2 : 'b list) =
monad {
for x in list1 do
for y in list2 do
return (x, y)
}
let sortResults (results : ('a * 'b) list) =
monad {
return results |> List.sortBy (fun (x, y) -> x.ToString())
}
let example () =
monad {
let! results = combineLists [1;2;3] ["a";"b";"c"]
let! sortedResults = sortResults results
return sortedResults
}
在这个示例中,我们使用了 MonadBuilder,而不是传统的 Computation Expression 语法。let!
表示绑定,在这个示例中它被用于组合器中。
这是一个简单的例子,但是对于更复杂的项目,将代码拆分成小的组件可以使代码更易于管理和调试。