类似于F#中的收益率突破

时间:2010-01-02 16:19:42

标签: f#

如果首先打破如何?

let WithdrawalCash (account, amount) = seq {        

    if ( account.Balance.CurrentAmount - amount < 0.0m) then
        yield NotEnoughMoneyForWithdrawal(account, amount)   
        // How to break here?     

    let newBalance = account.Balance.CurrentAmount - amount
    yield CashWithdrawnEvent(account, newBalance)
}

2 个答案:

答案 0 :(得分:6)

不确定这会有所帮助,为什么不使用else子句?

let WithdrawalCash (account, amount) = seq {        

   if ( account.Balance.CurrentAmount - amount < 0.0m) then
       yield NotEnoughMoneyForWithdrawal(account, amount)   
       // How to break here?     
   else 
      let newBalance = account.Balance.CurrentAmount - amount
      yield CashWithdrawnEvent(account, newBalance) 
}

另请看:

hubsFs - Break in F#?

Imperative computation in F# (II.) - Writing break and continue

hubsFs - yield break: deprecated or as-yet-unimplemented?

答案 1 :(得分:2)

发布的代码只会返回一个CashWithdrawlEvent,然后结束序列...你需要有一个循环来返回多个值。另外,您是否考虑过使用“匹配”来处理多个案例?

(未经测试工作......)

let WithdrawalCash (account, amount) = seq {         

    let bDone = ref false

    while not (!bDone) do
        match amount with
        | v when account.Balance.CurrentAmount - v < 0 ->
           yield NotEnoughMoneyForWithdrawal(account, amount)
           bDone := true    // break

        // more when clauses can go here

        | _ ->
          let newBalance = account.Balance.CurrentAmount - amount 
          yield CashWithdrawnEvent(account, newBalance) 
          // let the sequence continue

}

但是,即使这看起来不像你想要的那样,因为每次从序列中提取值时它总是会撤回相同的“数量”,因为在创建序列时帐户和金额是固定的。所以,我放弃'seq'并使其成为一个简单的函数,如:

let WithdrawalCash (account, amount) =

    match amount with
    | v when account.Balance.CurrentAmount - v < 0 ->
       NotEnoughMoneyForWithdrawal(account, amount)

    // more when clauses can go here

    | _ ->
      let newBalance = account.Balance.CurrentAmount - amount 
      CashWithdrawnEvent(account, newBalance) 

对于枚举某些序列并在满足特定条件时停止的一般情况,请考虑“Seq.takeWhile”,如:

let MySeq = seq {
    while true do
        yield someValue
    }

let code () =
    MySeq
    |> Seq.takeWhile ( fun v -> ShouldIContinueWorkingTest(v) )
    |> Seq.iter ( fun v -> DoWork(v) )