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

时间:2016-04-18 00:16:19

标签: visual-studio f# functional-programming interpreter discriminated-union

我正在尝试用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

我错过了什么吗?

2 个答案:

答案 0 :(得分:6)

扩展John Palmer的评论:

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

现在,您编写的checkType函数的返回类型是什么?由于您没有指定返回类型,编译器会查看可以从函数返回的值的类型 - 每个可能的代码分支都必须返回一个值,并且它们必须都是相同的类型。所以它会查看你的match语句,看到它的第一个分支返回string,然后说,"啊哈!我已经找到了这个函数的返回类型;这是一个带Expr并返回字符串的函数。函数的类型为Expr -> string。"

然后它会查看match语句的第二个分支,然后说,"等一下。这是一个返回string的函数,但在此代码分支中它返回int。这无效:调用此函数的代码需要知道期望它返回的类型。"所以你得到错误。

现在,如果您要交换match语句的顺序,首先检查Integer i,那么编译器会将您的函数评估为类型Expr -> int(取{ {1}}输入并返回Expr输出),并在int行上抛出错误。这一次,错误将是"等一下,这是一个返回| String s -> s的函数,因此这里的表达式int应该是s类型。但相反,它的类型为int。那是无效的。"

或删除string行,您会看到错误"此表达式应为| String s -> s类型,但此处的类型为int。&# 34;同样的事情:每个函数只能有一个返回类型。如果你想从一个函数中返回多个不同的可能类型,那就是被歧视的联盟所用的类型。

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

答案 1 :(得分:-1)

您可以将所有表达式包装到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