0

私ができることを望みます:

 let myFun param1 param2 = 
      .....
      if condition 1
          ....
          if condition 2
               yield ....

 let sequence = seq { for x in xs do
                            myFun 1 x
                            myFun 2 x
                    }

でも今はできることしかない

 let myFun param = 
      .....
      .....
      if condition 1
          ....
          if condition 2
               Some....
          else None    // has to complete else
      else None

 let sequence = seq { for x in xs do
                        match myFun 1 x with
                        | Some x -> yield x
                        | None   -> ()
                        match myFun 2 x with
                        | Some x -> yield x
                        | None   -> ()
                    }

  let sequence2 =  // order will be different, and we can not have index passed into function unless we do a futher Seq.map

       let a = xs |> Seq.choose (myFun 1)
       let b = xs |> Seq.choose (myFun 2)
       Seq.append a b

私の実際のコード:

コードはあまりよくないように見えますがNone、 を試してみSeq.chooseましたが、 をサポートしていないためあまり役に立ちませんSeq.choosei

        let exam isForward brickID =
            let brick = state.[brickID]
            let (nextTR, nextOccupied, nextUnoccupied) = if isForward then brick.Body.nudgeForward () else brick.Body.nudgeBack ()
            if (nextOccupied.isInGrid gridSize) && (map.ContainsKey nextOccupied |> not) then
                let nextBrick = { brick with Body = nextTR }
                let nextState = getNextState state brickID nextBrick
                if not (explored.Contains nextState) then
                    let nextMap = map |> Map.remove nextUnoccupied
                                      |> Map.add nextOccupied nextBrick
                    Some ((nextState, nextMap), (nextBrick, if isForward then brick.Body.Direction else brick.Body.Direction.Opposite))
                else None
            else None

        seq { for brickID in 0 .. state.Length - 1 do
                match exam true brickID with
                | Some x -> yield x
                | None   -> ()
                match exam false brickID with
                | Some x -> yield x
                | None   -> ()
        }
4

2 に答える 2

5

関数examは、( の代わりに) 空であるか、( の代わりにNone) 1 つの要素のみを含むシーケンスを返し、指定されたシーケンスのすべての要素を現在生成しているシーケンスに追加することをSome使用できます。yield!

疑似コード サンプルでは、​​これは次のようになります。

let myFun param1 param2 param3 = seq {
  if param1 then
    if param2 then
      yield param3 }

 let sequence = seq { 
   for x in xs do
     yield! myFun true true x 
     yield! myFun true true (x * 10) }

xs = [1;2]上記のサンプルが生成されると仮定し[1; 10; 2; 20]ます (そして、いくつかのtrue引数をfalseに設定すると、いくつかの数値がスキップされます)

于 2013-01-18T16:01:39.613 に答える
2

この例では、@Tomas による回答が最良のアプローチです。ただし、 Option モジュールの便利な関数を使用する別の選択肢がまだあります。

let sequence = seq { for x in xs do
                        yield! Option.toList (myFun 1 x)
                        yield! Option.toList (myFun 2 x)
                    }

これは、 のカスタマイズされたバージョンとして表示できますSeq.choose

于 2013-01-18T21:52:06.253 に答える