type tradeLeg = {
id : int ;
tradeId : int ;
legActivity : LegActivityType ;
actedOn : DateTime ;
estimates : legComponents ;
entryType : ShareOrDollarBased ;
confirmedPrice: DollarsPerShare option;
actuals : legComponents option ;
type trade = {
id : int ;
securityId : int ;
ricCode : string ;
tradeActivity : TradeType ;
enteredOn : DateTime ;
closedOn : DateTime ;
tradeLegs : tradeLeg list ;
}
一个记录显然tradeLegs是一种关贸易。支腿可以解决或悬空(或不安但价格确认) - 因此,我已经定义了有源图案:
let (|LegIsSettled|LegIsConfirmed|LegIsUnsettled|) (l: tradeLeg) =
if Helper.exists l.actuals then LegIsSettled
elif Helper.exists l.confirmedPrice then LegIsConfirmed
else LegIsUnsettled
,然后,以确定是否一个贸易结算(基于所有腿匹配LegIsSettled图案:
let (|TradeIsSettled|TradeIsUnsettled|) (t: trade) =
if List.exists (
fun l ->
match l with
| LegIsSettled -> false
| _ -> true) t.tradeLegs then TradeIsSettled
else TradeIsUnsettled
我可以看到这种使用活动模式的一些优点,但我认为有一种更有效的方法来查看列表中的任何项目是否匹配(或不)没有写入的行为模式一个专门用于它的lambda表达式,并使用List.exist。
问题有两方面:
- 有没有更简洁的表达方式呢?
是有办法抽象的功能/表达
(fun l -> match l with | LegIsSettled -> false | _ -> true)
使得
let itemMatchesPattern pattern item =
match item with
| pattern -> true
| _ -> false
这样可以写(如我重用这个设计模式):
let curriedItemMatchesPattern = itemMatchesPattern LegIsSettled
if List.exists curriedItemMatchesPattern t.tradeLegs then TradeIsSettled
else TradeIsUnsettled
想法?
+1:coolness!我不知道你可以将'(| Odd | _ |)'作为一个值传递给函数:) – Juliet 2010-04-19 23:40:05
我很惊讶,当我发现这是可能的。实际上,活动模式有点像运营商。通过运算符,可以声明'let(++)a b = a + b'并使用它们'List.map(++)'。使用活动模式:'let(| Xyz | _ |)a = None'和'List.map(| Xyz | _ |)'(名称中的空格实际上也是允许的!) – 2010-04-19 23:45:14
谢谢。我原本是将它写成标准功能(尽管不那么雄辩),并且开始用主动模式来玩弄*解锁他们的力量。好的信息在那里 - 再次感谢你 – akaphenom 2010-04-20 00:07:49