Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# F模式匹配:当构造器使用不当时,“as”如何解释?_F# - Fatal编程技术网

F# F模式匹配:当构造器使用不当时,“as”如何解释?

F# F模式匹配:当构造器使用不当时,“as”如何解释?,f#,F#,我有一个受歧视的联盟,其选择类型为另一个du,如下所示: type DunionSubset = | X | Y type Dunion = | A | B | C of DunionSubset let MappingsOfC = function | X -> ["x"] | Y -> ["y"] let StringMappings = function | A -> ["a";"A"] | B

我有一个受歧视的联盟,其选择类型为另一个du,如下所示:

type DunionSubset =
    | X
    | Y
type Dunion =
    | A
    | B
    | C of DunionSubset
let MappingsOfC = function
    | X -> ["x"]
    | Y -> ["y"]

let StringMappings = function
    | A -> ["a";"A"]
    | B -> []
    | C  as c -> (MappingsOfC c)
我想为Dunion类型生成一个到字符串列表的映射,它自然地扩展到C,从而扩展到DunionSubset

当我错误地使用as为构造函数分配别名时,如下所示:

type DunionSubset =
    | X
    | Y
type Dunion =
    | A
    | B
    | C of DunionSubset
let MappingsOfC = function
    | X -> ["x"]
    | Y -> ["y"]

let StringMappings = function
    | A -> ["a";"A"]
    | B -> []
    | C  as c -> (MappingsOfC c)
编译器给了我:

[FS0019] This constructor is applied to 0 argument(s) but expects 1
我不正确地使用上述as是如何导致此编译器错误的?有趣的是,编译器错误的位置是C的位置,而不是我在映射中使用的C。C在C下面加了下划线,并提供了一个不同的错误。

C因为C将函数参数与模式C匹配,并将其绑定到C。因此,这与:

let StringMappings c = match c with
    | A -> ["a";"A"]
    | B -> []
    | C -> (MappingsOfC c)
但这将使c在所有分支中可见,而带有as的版本仅使c在具有as模式的分支中可见

因为C接受一个参数,所以会出现一个错误,但您试图在没有参数的情况下使用它。如果您将| A作为A->、|B作为B->和/或| C作为C编写,则可以正常工作。

C作为C将函数参数与模式C匹配,并将其绑定到C。因此,这与:

let StringMappings c = match c with
    | A -> ["a";"A"]
    | B -> []
    | C -> (MappingsOfC c)
但这将使c在所有分支中可见,而带有as的版本仅使c在具有as模式的分支中可见

因为C接受一个参数,所以会出现一个错误,但您试图在没有参数的情况下使用它。如果您将| A作为A->、|B作为B->和/或| C作为C编写,这将很好。

实际上,如果匹配分支中提供了模式,则在as和when关键字之前的->的左侧部分。和模式必须有效-取决于匹配关键字后面提供的值的类型

在这里,编译器将理解您想要匹配一个Dunion值,因为它首先看到了所有有效的模式a和B

现在你可以看到C对于Dunion来说是一个无效的模式。这里的有效模式必须是:C

如果您不关心一些不需要使用的东西,那么仍然必须提供一个通配符,以使模式有效:C_

但在您的示例中,我很确定您确实关心,因此代码应该如下所示:

| C c -> MappingsOfC c
实际上,如果在匹配的分支中提供了一个模式,那么as和when关键字前面的->的左侧部分就是一个模式。和模式必须有效-取决于匹配关键字后面提供的值的类型

在这里,编译器将理解您想要匹配一个Dunion值,因为它首先看到了所有有效的模式a和B

现在你可以看到C对于Dunion来说是一个无效的模式。这里的有效模式必须是:C

如果您不关心一些不需要使用的东西,那么仍然必须提供一个通配符,以使模式有效:C_

但在您的示例中,我很确定您确实关心,因此代码应该如下所示:

| C c -> MappingsOfC c

谢谢,特别是用显式匹配解释表单。谢谢,特别是用显式匹配解释表单。