F#-模式匹配歧视并集时的怪异行为

F#-模式匹配歧视并集时的怪异行为,f#,F#,我已经写了6个月的F#了,我遇到了一些我无法解释的行为。下面我有一些简单的代码。(已更改值名称以保护无辜者!) 我有一个使用记录类型rec1和rec2定义的层次结构,还有一个可能值为CaseA和CaseB的区分联合类型。我正在调用一个采用du_rec选项类型的函数('mynewfunc')。在内部,该函数定义了一个处理层次结构的递归函数 我通过传递None选项值来表示层次结构的根(实际上,此函数是从文件反序列化层次结构)来启动处理 当我运行下面的代码时,我点击了代码的“failwith”“inv

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

我有一个使用记录类型rec1和rec2定义的层次结构,还有一个可能值为CaseA和CaseB的区分联合类型。我正在调用一个采用du_rec选项类型的函数('mynewfunc')。在内部,该函数定义了一个处理层次结构的递归函数

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

当我运行下面的代码时,我点击了代码的“failwith”“invalid parent”行。我无法理解这是为什么,因为传递的None值应该与外部模式匹配的None大小写匹配

如果我删除任何一组注释,代码都可以工作。这对我来说并不是一个阻碍,我只是觉得有点不舒服,不知道为什么会发生这种情况(我以为我理解f#)

提前感谢您的回复

詹姆斯


根据注释,这只是调试器中的一次糟糕体验(突出显示表明控制流正在进行它没有进行的地方);代码实现了您的期望


(有许多地方F#编译器可以改进生成到PDB中的序列点,以改善调试体验;我认为我们将在未来的版本中对此进行研究。)

根据评论,这只是调试器中的一种糟糕体验(高亮显示表明控制流正在进行,而不是在进行);代码实现了您所期望的


(在许多地方,F#编译器可以改进生成到PDB中的序列点,以改善调试体验;我认为我们将在未来的版本中研究这一点。)

您不需要在du_rec中使用
。但不确定这是否有帮助。原始代码的格式有点不正确,没有编译。我已经修复了它,所以它可以编译。我也在我的机器上测试了它,它似乎工作正常。您能描述一下您使用的环境(可能是mono吗?)使用F#和FSI版本号?请注意,您的字段名相互冲突。我不明白您对此的确切期望…感谢您的回复。我正在Windows 7 Prof上使用Visual Studio 2010(Microsoft Visual Studio 2010-版本10.0.30319.1 RTMRel)。我已经分离了du_rec类型并重新运行代码。在单步执行代码时,failwith行会高亮显示,但不会引发异常。我已将该行替换为printfn-printfn会高亮显示,但不会打印任何内容。看起来这可能是调试器没有反映执行过程中发生的情况哦,f#version是2.0,我的fsi版本是4.0.30319.1。感谢大家对此进行研究-我确信这是突出显示当前语句的调试器组件中的一个错误。您不需要对du_rec使用
。但不确定这是否有帮助。原始代码的格式有点错误,没有编译。我已经修复了它,因此它是compiles。我也在我的机器上测试过,它似乎工作得很好。你能描述一下你正在使用的环境吗(可能是mono?)使用F#和FSI版本号?请注意,您的字段名相互冲突。我不明白您对此的确切期望…感谢您的回复。我正在Windows 7 Prof上使用Visual Studio 2010(Microsoft Visual Studio 2010-版本10.0.30319.1 RTMRel)。我已经分离了du_rec类型并重新运行代码。在单步执行代码时,failwith行会高亮显示,但不会引发异常。我已将该行替换为printfn-printfn会高亮显示,但不会打印任何内容。看起来这可能是调试器没有反映执行过程中发生的情况哦,f#version是2.0,我的fsi版本是4.0.30319.1。感谢大家的关注-我确信这是突出显示当前语句的调试器组件中的一个错误。感谢Brian,下面的代码甚至更短,也会混淆调试器:将2与| 1->printfn“one”|->()感谢Brian,下面的代码甚至更短,而且还混淆了调试器:将2与| 1->printfn“one”| |->()
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)