rys*_*ama 2 f# options pattern-matching
任何人都知道这段代码的问题是什么?
let rec Foo(a,b) =
match a () with
| None -> Some(b)
| Some(c) -> Some(Foo(c,b))
Run Code Online (Sandbox Code Playgroud)
这是编译器错误:
"类型不匹配.期待'a但给定'一个选项结果类型在统一''a'和''选项'时将是无限的"
让我们尝试重现编译器如何在此处推断类型.
let rec Foo(a,b) =
match a () with
| None -> Some(b)
| Some(c) -> Some(Foo(c,b))
Run Code Online (Sandbox Code Playgroud)
"好吧,所以我明白了a ()
.a
必须是unit
某种类型的函数,我还不知道哪一种.我会称之为'a
."
a : unit -> 'a
Run Code Online (Sandbox Code Playgroud)
"结果a ()
与None
/ Some
patterns 相匹配.所以'a
必须是a 'b option
并且c
有类型'b
." (再次,'b
代表一个未知的,至今,类型).
a : unit -> 'b option
? : 'b
Run Code Online (Sandbox Code Playgroud)
"没有调用任何函数或方法b
(除了Some
,它不会缩小类型,以及Foo
到目前为止我们不知道的类型).我将用它来表示它的类型'c
."
a : unit -> 'b option
b : 'c
c : 'b
Run Code Online (Sandbox Code Playgroud)
" Foo
返回Some(b)
的分支之一,因此,返回类型必须是'c option
."
Foo : (unit -> 'b option) * 'c -> 'c option
Run Code Online (Sandbox Code Playgroud)
"我完成了吗?不,我需要检查表达式中的所有类型是否有意义.让我们看看,在这种Some(c)
情况下,Some(Foo(c,b))
返回.所以Foo(c,b) : 'c
.因为Foo
返回一个option
,我知道'c
必须'd option
为某些'd
,并且b : 'd
.等等,我已经有b : 'c
,那就是b : 'd option
,'d
和'd option
必须是同类型的,但是这是不可能的!必须有定义一个错误.我要报的." 它确实如此.
归档时间: |
|
查看次数: |
238 次 |
最近记录: |