k1u*_*k1u 3 f# interpreter functional-programming visual-studio discriminated-union
我想在F#写一个翻译.我想检查表达式的类型.
这是我对表达式的歧视联盟
type Expr =
| Integer of int
| String of string
| Boolean of bool
Run Code Online (Sandbox Code Playgroud)
这是我用来检查类型的方法
let checkType (e:Expr) =
match e with
| String s -> s
| Integer i -> i
| Boolean b -> b
Run Code Online (Sandbox Code Playgroud)
我希望方法确定表达式是字符串,整数还是布尔值.
但是,visual studio在checkType方法的第4行给出了以下错误:
This expression was expected to have type string but here has type int
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?
扩展John Palmer的评论:
F#期望每个函数都有一个返回类型.例如,您可以编写一个接受int的函数并返回一个int,它将是一个类型的函数int -> int.将字符串解析为int的函数将是类型string -> int.等等.
现在,checkType您编写的函数的返回类型是什么?由于您没有指定返回类型,编译器会查看可以从函数返回的值的类型 - 每个可能的代码分支都必须返回一个值,并且它们必须都是相同的类型.所以它查看你的match语句,看到它的第一个分支返回一个string,然后说:"啊哈!我已经找到了这个函数的返回类型;这个函数接受一个Expr并返回一个字符串.函数的类型是Expr -> string".
然后它查看match语句的第二个分支,并说:"等一下.这是一个返回a的函数string,但是在这个代码分支中它返回一个int.这是无效的:调用这个函数的代码需要知道什么打算期望它返回." 所以你得到了错误.
现在,如果要交换match语句的顺序,Integer i首先检查,然后编译器会将您的函数计算为具有类型Expr -> int(获取Expr输入并返回int输出),并在该| String s -> s行上抛出错误.这一次,错误将是"等一下,这是一个返回一个函数int,所以s这里的表达式应该是类型int.但相反,它是类型string.这是无效的."
或者删除该| String s -> s行,你会看到一个错误"这个表达式应该有类型,int但这里有类型bool." 同样的事情:每个函数只能有一个返回类型.如果您想从函数中返回多种不同的可能类型,那就是Discriminated Unions所针对的类型.
有关F#类型的更多阅读,请参阅http://fsharpforfunandprofit.com/series/understanding-fsharp-types.html.