将表达式树解析为嵌套列表

时间:2016-05-20 09:49:06

标签: f# expression-trees

我对F#比较陌生,我真的很难解析包含嵌套列表的表达式树。从网上的点点滴滴中,我拼凑了以下内容。

我的标准类型已定义:

type Return = 
    | Real of float
    | Func of string * Return list

我对外部应用程序进行函数调用,返回类似于:

的内容
val out : Return =
    Func
        ("List",
             [Func ("List",[Real 1.0; Real 2.0; Real 3.0]);
              Func ("List",[Real 1.0; Real 2.0; Real 3.0]);
              Func ("List",[Real 1.0; Real 2.0; Real 3.0])])

我需要解析

[ [1.0; 2.0; 3.0] ; [1.0; 2.0; 3.0] ; [1.0; 2.0; 3.0] ]

我最初的天真想法是

let rec parse data =
    match data with
    | Real(y) -> y
    | Func("List", x) -> x |> List.map parse 
    | _ -> failwithf "Unrecognised"

但它抱怨类型差异,我现在明白了。

我的第二个想法是可能使用一些递归的List.fold(因为我可以折叠Reals列表并获取内部列表,但是无法弄清楚如何在没有编译器的情况下将其推广到递归函数中抱怨类型)。超越我目前的智力火力。

我的第三个想法是,我从外部应用程序获得的回报可能使得这太难了,因为在元组fst中没有关于元组snd中的内容的指示,除了它是&#34的事实;某事物清单"?

有这样的:Convert tree to list但它与我尝试的解决方案一样神秘。

关于我追求的途径的任何指示都会非常感激。

2 个答案:

答案 0 :(得分:2)

您希望parse函数返回的对象类型是什么?

如果您的所需输出为[ [1.0; 2.0; 3.0] ; [1.0; 2.0; 3.0] ; [1.0; 2.0; 3.0] ],则您希望返回的内容既不是float list也不是float list list,而是任意嵌套列表 float

但是这不作为标准类型存在,并且您需要将其自身定义为递归区分联合(我们将其作为良好实践的通用):

type NestedList<'a> = 
    | Single of 'a
    | Collection of NestedList<'a> list

好好看看!它比原来的Return类型更薄。这是因为原始类型几乎已经是标准的嵌套列表实现,除了"List"标签之外。

parse函数几乎没有任何实际工作要做:

let rec parse = function
    | Real y ->  Single y
    | Func ("List", returns) -> Collection (returns |> List.map parse)
    | Func (l, _) -> failwithf "Unrecognised label %s" l

答案 1 :(得分:1)

有时注释您正在实现的功能是件好事。然后它就明确了你要做的事情:

type Return = 
    | Real of float
    | Func of string * Return list

let rec parse (data : Return) : float list =
    match data with
    | Real y ->  [ y ]
    | Func (_, returns) -> returns |> List.collect parse
    | _ -> failwithf "Unrecognised"

您的x |> List.map parse类型为float list list,但在其他分支上,您的表达式的类型为float。我是否正确您尝试返回float list