F# - 模式匹配区分联合时的奇怪行为

时间:2011-01-12 16:55:03

标签: f#

我已经写了一些F#现在大约6个月了,我遇到了一些我无法解释的行为。我在下面有一些简化的代码。 (值名称已被更改以保护无辜者!)

我有一个使用记录类型rec1和rec2定义的层次结构,以及一个具有可能值CaseA和CaseB的判别联合类型。我正在调用一个带有du_rec选项类型的函数('mynewfunc')。在内部,此函数定义了一个处理层次结构的递归函数。

我通过传递None选项值来表示层次结构的根来开始处理(实际上,此函数正在从文件中反序列化层次结构)。

当我运行下面的代码时,我点击了“failwith”无效的父代码“”。我无法理解为什么会这样,因为传递的None值应该匹配外部模式匹配的None case。

如果我删除任何一组评论,代码都有效。这对我来说不是一个好处 - 我只是觉得有点不舒服,不知道为什么会这样(我以为我理解f#)

提前感谢您的回复

詹姆斯

type rec2 =
    { 
    name : string 
    child : rec1 option
    }
and rec1 =
    { 
    name : string ; 
    child : rec2 option
    }
and du_rec =
    | Case1 of rec1 
    | Case2 of rec2


let mynewfunc (arg:du_rec option) =
    let rec funca (parent:du_rec option) =
        match parent with
        | Some(node) -> 
            match node with
            | Case2(nd)  ->
                printfn "hello"
            (* | Case1(nd) ->
                printfn "bye bye" *)
            | _ -> 
                failwith "invalid parent"
        | None ->
                // printfn "case3"
                ()
        funcb( None )
    and funcb (parent: du_rec option) =
        printfn "this made no difference"
    let node = funca(arg)
    ()

let rootAnnot = mynewfunc(None)

1 个答案:

答案 0 :(得分:3)

基于这些评论,这只是调试器中的一个糟糕体验(突出显示表明控制流正在发生的地方不是这样);代码符合您的期望。

(有很多地方F#编译器可以改进其生成到pdbs中的序列点,以改善调试体验;我想我们将在未来版本中考虑这一点。)