F#Disriminated Union - "向下转型"到子类型

Mar*_*rta 4 f# discriminated-union

我真的不知道这个问题的正确标题应该是什么,但是:

我已经叫区分联合MyDiscriminatedUnionF#:

type MyDiscriminatedUnion =
| Foo of Foo
| Bar of Bar
Run Code Online (Sandbox Code Playgroud)

在哪里FooBar是记录类型:

type Foo = {
   ... }
type Bar = {
   ... }
Run Code Online (Sandbox Code Playgroud)

我创建了一个union类型的值Foo:

let foo = Foo {
   ... }
Run Code Online (Sandbox Code Playgroud)

编译器告诉我foo是类型的MyDiscriminatedUnion.

然后我想将foo传递给一个期望类型为Foo的函数,而不是MyDiscriminatedUnion.因此编译器抱怨.如何告诉编译器foo类型Foo

我试过了:

let foo:Foo 
Run Code Online (Sandbox Code Playgroud)

在构造union类型的值时.

我试图通过以下方式"向下"foo到Foo:

foo :?> MyDiscriminatedUnion.Foo
Run Code Online (Sandbox Code Playgroud)

但它们都不起作用.

请帮忙.

Tar*_*mil 10

来自OO语言时这是一个常见的错误:此代码中没有涉及子类型.你将你的联合案例命名为与它们包含的字段类型相同的事实可能会让人感到困惑,所以让我给出一个稍微不同的例子:

type MyDiscriminatedUnion =
  | Its_a_Foo of Foo
  | Its_a_Bar of Bar
Run Code Online (Sandbox Code Playgroud)

Its_a_FooIts_a_Bar不是亚型,他们是工会的情况.type的值MyDiscriminatedUnion是a Its_a_Foo,在这种情况下,它有一个类型的字段Foo,或者a Its_a_Bar,在这种情况下,它有一个类型的字段Bar.要知道它是哪一个并获得相应的字段,您需要使用模式匹配.

// The function that takes a record of type Foo as argument
let f (x: Foo) = ...

// Our value of type MyDiscriminatedUnion
let myDU = Its_a_Foo { ... }

// Extracting the Foo and passing it to f
match myDU with
| Its_a_Foo foo -> f foo
| Its_a_Bar bar -> // What should we do if it's an Its_a_Bar instead?

// If you're _really_ certain that myDU is Its_a_Foo { ... }, not Its_a_Bar { ... }, you can do this.
// You will get a compile-time warning "FS0025: Incomplete pattern matches on this expression".
// If it's Its_a_Bar, you will get a runtime error.
let (Its_a_Foo foo) = myDU
f foo
Run Code Online (Sandbox Code Playgroud)

  • "*如果它是Its_a_Bar,你将收到一个错误.*"_runtime_错误,而不是编译器错误,值得指出. (3认同)