这个List表达式出了什么问题?

时间:2013-12-30 02:56:53

标签: 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,但编译器会抱怨对evaluate的调用应该有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)})

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

2 个答案:

答案 0 :(得分:1)

我只是错过了一个yield关键字:

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

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

答案 1 :(得分:0)

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

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

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