代码的一小部分,以突出问题:
open System.IO
let do_smth i (stm : #System.IO.Stream) = // val do_smth : 'a -> #Stream -> unit
(*....*)
()
type SomeOps = SomeOps with
static member op (i : int) = do_smth i
let test_currying i = do_smth i // val test_currying : 'a -> (Stream -> unit)
// NB: Stream, not #Stream
let main() =
use stm = new System.IO.MemoryStream()
test_currying 42 stm // OK, upcasted to Stream somehow
SomeOps.op 42 stm // compiler error!
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下,为什么编译器的行为在最后两行中如此不同?为什么我们#Stream在test_currying功能上丢失了信息(关于灵活性)?
这对我来说看起来像是一个错误。编译器处理使用不同构造的函数let和编写为static member.
特别是,我认为它不会为未在成员声明中显式声明的成员参数插入灵活类型(即,参数要么是部分函数应用程序的结果,要么是使用构造创建的参数fun)。
演示该行为的最简单示例不使用灵活类型,如下所示:
type A =
static member op = fun (s:obj) -> ()
module B =
let op = fun (s:obj) -> ()
A.op "A" // Error
B.op "A" // Ok
Run Code Online (Sandbox Code Playgroud)
根据规范(第14.4.2节,由 Brian 在删除的(?)答案中发布),无论调用的函数是成员还是 let 绑定值,都应该插入允许使用超类型的灵活类型。
| 归档时间: |
|
| 查看次数: |
260 次 |
| 最近记录: |