我正在尝试用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
我错过了什么吗?
答案 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