3

我试图在F#中编写一个解释器。我想检查表达式的类型。在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 

我想要的方法来确定阉一个表达式来检查类型的方法识别联合是一个字符串,整数或布尔值。

然而,视觉工作室给我的checkType方法的4线以下错误:

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

我这么想吗?

+6

当前的错误是由于一个事实,即函数只能返回一个类型的表达式 –

回答

6

要扩大约翰·帕尔默的评论:

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

现在,你写的checkType函数的返回类型是什么?由于您没有指定返回类型,因此编译器会查看可以从函数返回的值的类型 - 每个可能的代码分支都必须返回一个值,并且它们都必须是相同的类型。所以它看着你的match声明,看到它的第一个分支返回一个string,并且说:“啊哈!我已经计算出此函数的返回类型;这是一个函数,它需要一个Expr并返回一个字符串。函数的类型是Expr -> string。“

然后看你match语句的第二个分支,并说,“等一下这是返回一个string的功能,但在这个代码分支它返回一个int这不是有效的:。该代码调用这个函数需要知道什么类型期望它返回。“所以你会得到错误。现在

,如果你换你的match陈述案件的顺序,检查Integer i第一,那么编译器将评估你的函数具有类型Expr -> int(服用Expr输入并返回int输出),并抛出一个错误在| String s -> s行。这一次,错误将是“等一下,这是一个返回int的函数,所以表达式s应该是int类型,但是它的类型是string,这是无效的。”

或删除| String s -> s行,您将看到一个错误“此表达式预计有int类型,但此处有类型bool。”同样的事情:每个函数只能有一个返回类型。如果你想从一个函数返回多种不同的可能类型,那就是歧视联盟的用途。请参阅http://fsharpforfunandprofit.com/series/understanding-fsharp-types.html

+0

非常明确的解释,谢谢。 – k1u

-1

你可以用所有的表达式为选项类型像一些或字符串:

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 
相关问题