我最近开始使用计算表达式来简化我的代码。到目前为止,对我来说唯一有用的是 MaybeBuilder,它是这样定义的:
type internal MaybeBuilder() =
member this.Bind(x, f) =
match x with
| None -> None
| Some a -> f a
member this.Return(x) =
Some x
member this.ReturnFrom(x) = x
但我想探索其他用途。一种可能性是我目前面临的情况。我有一些定义对称矩阵的供应商提供的数据。为了节省空间,只给出了矩阵的三角形部分,因为另一边只是转置。因此,如果我在 csv 中看到一行
美国广播公司,高清,123
这意味着行 abc 和列 def 的值为 123。但我不会看到诸如
定义,美国广播公司,123
因为由于矩阵的对称性,该信息已经给出。
我已经在 a 中加载了所有这些数据,Map<string,Map<string,float>>
并且我有一个函数可以为我获取任何看起来像这样的条目的值:
let myLookupFunction (m:Map<string,Map<string,float>>) s1 s2 =
let try1 =
match m.TryFind s1 with
|Some subMap -> subMap.TryFind s2
|_ -> None
match try1 with
|Some f -> f
|_ ->
let try2 =
match m.TryFind s2 with
|Some subMap -> subMap.TryFind s1
|_ -> None
match try2 with
|Some f -> f
|_ -> failwith (sprintf "Unable to locate a value between %s and %s" s1 s2)
现在我知道了计算表达式,我怀疑匹配语句可以被隐藏。我可以像这样使用 MaybeBuilder 稍微清理一下
let myFunction2 (m:Map<string,Map<string,float>>) s1 s2 =
let maybe = new MaybeBuilder()
let try1 = maybe{
let! subMap = m.TryFind s1
return! subMap.TryFind s2
}
match try1 with
|Some f -> f
|_ ->
let try2 = maybe{
let! subMap = m.TryFind s2
return! subMap.TryFind s1
}
match try2 with
|Some f -> f
|_ -> failwith (sprintf "Unable to locate a value between %s and %s" s1 s2)
这样做,我已经从 4 个匹配语句变成了 2 个。有没有一种(不是人为的)方法可以通过使用计算表达式来进一步清理它?