C#到F#循环以返回值

C#到F#循环以返回值,c#,f#,C#,F#,如何用f编写这段代码# [错误] 这个表达式应该有int类型,但这里有unit类型。虽然你可以一行一行地把C代码重写成F代码,但这样你就不会得到F的优雅了。我建议先处理一些非常简单的问题(比如处理列表),然后再考虑如何将项目设计得更加实用 要回答您的问题,您可以使用List.tryFind而不是循环和变异: let idx = [ 0 .. 8 ] |> List.tryFind (fun i -> cBoard.getPlayer(i) = 0) 这将生成一个从0到1的数字列表,

如何用f编写这段代码#

[错误] 这个表达式应该有int类型,但这里有unit类型。虽然你可以一行一行地把C代码重写成F代码,但这样你就不会得到F的优雅了。我建议先处理一些非常简单的问题(比如处理列表),然后再考虑如何将项目设计得更加实用

要回答您的问题,您可以使用
List.tryFind
而不是循环和变异:

let idx = [ 0 .. 8 ] |> List.tryFind (fun i -> cBoard.getPlayer(i) = 0)
这将生成一个从0到1的数字列表,然后返回第一个数字,这样给定的谓词将返回true。这与代码的行为稍有不同-它返回
选项
,如果未找到值,则返回
,或者在找到值时返回
某些(i)


使用选项和模式匹配可能是一个好主意,但是如果找不到值,可以使用
defaultArg idx 0
返回0。

如果坚持保留代码C#ish:


将==更改为
结果:=一些i
,但请注意,它将继续循环并返回最后一个有效的
i
。无相同错误。早就试过了为什么要用列表?没有必要存储所有的数字。最好使用
seq{0..8}
@SargeBorsch,因为OP显然在学习F#,我想我应该使用最简单的类型。另外,对于8个元素,差异实际上并不重要。但是,您是对的,使用sequence更有意义。this.AIMove()是一个接口的实现。我如何使用你的功能?顺便问一下,为什么
defaultArg
的参数顺序是这样的?这使得它非常不适合部分应用程序…定义一个
flip
函数:)@RamonSnir当然可以,但这是额外的一步。或者它已经在F#中?它在FSharpX中(或者曾经,有一段时间没有更新)。如果找不到任何内容,则函数必须返回0
member this.AIMove()=
      let result =  int in
        for i in 1 .. 8 do
            if cboard.getPlayer(i)=0 then
               result := Some i
let idx = [ 0 .. 8 ] |> List.tryFind (fun i -> cBoard.getPlayer(i) = 0)
member this.AIMove () : int option =
  let result = ref None
  for i in 1 .. 8 do
    if cboard.getPlayer(i)=0 then
      result := Some i
  match !result with
  | Some i -> i
  | None -> 0
type Board =
    member x.getPlayer (i: int) = 0 // Just a stub to allow typechecking

let move (cBoard: Board) =
    let isZero x = x = 0
    let found = seq { 0 .. 8 } |> Seq.tryFind (cBoard.getPlayer >> isZero)
    defaultArg found 0