F# 中具有不同 return 类型的可区分联合类型检查

Discriminated union type checking in F# with differernt return types

我正在尝试用 F# 编写解释器。我想检查表达式的类型。

这是我对表达式的区分并集

type Expr =
| Integer of int
| String of string
| Boolean of bool

这是我用来检查类型的方法

let checkType (e:Expr) =
match e with 
| String s -> s
| Integer i -> i
| Boolean b -> b

我想要确定表达式是字符串、整数还是布尔值的方法。

但是,visual studio 在 checkType 方法的第 4 行给我以下错误:

 This expression was expected to have type string but here has type int

我是不是漏了什么?

扩展 John Palmer 的评论:

F# 期望每个函数都有一个 return 类型。例如,您可以编写一个接受一个 int 和 returns 一个 int 的函数,这将是一个 int -> int 类型的函数。将字符串解析为整数的函数的类型为 string -> int。等等。

现在,您编写的 checkType 函数的 return 类型是什么?由于您没有指定 return 类型,编译器会查看您可以从函数中 return 的值的类型——每个可能的代码分支都必须 return 一个值,并且它们必须都是同一类型。所以它查看您的 match 语句,发现它的第一个分支 return 是 string,然后说 "Ah ha! I've figured out the return type of this function; this is a function that takes an Expr and returns a string. The function's type is Expr -> string."

然后它查看您的 match 语句的第二个分支,并说,"Wait a minute. This is a function that returns a string, but in this code branch it's returning an int. That's not valid: the code that calls this function needs to know what type to expect it to return." 所以您得到了错误。

现在,如果您要交换 match 语句案例的顺序,首先检查 Integer i,那么编译器会将您的函数评估为具有类型 Expr -> int(取Expr 输入和 returning int 输出),并在 | String s -> s 行抛出错误。这次,错误将是 "Wait a minute, this is a function that returns an int, so the expression s here should have been of type int. But instead, it's of type string. That's not valid."

或者删除 | String s -> s 行,你会看到一个错误 "This expression was expected to have type int but here has type bool." 同样的事情:每个函数只能有一个 return 类型。如果您想从一个函数中 return 多种不同的可能类型,这就是可区分联合的用途。

有关 F# 类型的更多阅读,请参阅 http://fsharpforfunandprofit.com/series/understanding-fsharp-types.html

您可以将所有表达式包装到一个 Option 类型中,例如 Some 或 String:

let checkType (e:Expr) =
    match e with
    | String e -> "we are string: " + string e
    | Integer e-> "we are integer: " + string e
    | Boolean e -> "we are boolean: " + string e