这个列表表达式有什么问题?

  • 本文关键字:问题 列表 表达式 f#
  • 更新时间 :
  • 英文 :


我有一个递归函数,可以创建如下所示的树:

let rec evaluate node = 
    let neighbors = getNeighbors node
    let visited = [for x, y in neighbors do
                       if not tiles.[y].[x] then
                           tiles.[y].[x] <- true
                           evaluate (x, y)]
    if List.length visited > 0 then 
        Node(x, y, visited) 
    else 
        Leaf(x, y)

Node 和 Leaf 来自这个定义:

type Tree =
    | Leaf of int * int
    | Node of int * int * Tree list

tiles是一个二维布尔数组,表示访问了哪些瓷砖(我正在实现迷宫生成)。

现在上面的函数无法编译。推断的类型是int*int -> unit,而它应该是int*int -> Tree

我试图强制返回类型Tree,但随后编译器抱怨对评估的调用应该具有类型 unit 但类型为 Tree

我找到了使用序列表达式并转换为列表的解决方法:

let visited = Seq.toList (seq { 
                for x, y in neighbors do
                    if not tiles.[y].[x] then
                        tiles.[y].[x] <- true
                        yield evaluate (x, y)})

但我不明白为什么使用列表表达式不起作用。

我只是缺少一个yield关键字:

let visited = [for x, y in neighbors do
                   if not tiles.[y].[x] then
                       tiles.[y].[x] <- true
                       yield evaluate (x, y)]

这将编译并且不需要强制返回类型。

对于列表表达式,您需要将do替换为-> - 请参阅此处 http://msdn.microsoft.com/en-us/library/dd233224.aspx

此外,在这种情况下,右侧必须具有一致的类型。 我会把它改成

[for x, y in (neighbors |> List.filter (fun (x2,y2) -> not tiles.[y2].[x2])) -> ...

最新更新