在F#中讨论'灵活类型'

时间:2012-03-16 20:00:25

标签: types f# currying

突出问题的代码的一小部分:

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!

有人可以解释,为什么编译器的行为在最后两行中如此不同?为什么我们在#Stream函数中丢失了信息(关于灵活的test_currying)?

1 个答案:

答案 0 :(得分:3)

对我来说这看起来像个错误。编译器处理使用let构造的不同函数和编写为static member的函数。

特别是,我认为它不会为未在成员声明中显式声明的成员参数插入灵活类型(即,部分函数应用的结果或使用{{1}创建的参数}构造)。

演示行为的最简单示例不使用灵活类型,如下所示:

fun

根据规范(部分14.4.2,由Brian在删除的(?)答案中发布),无论被调用的函数是成员还是let-bound,都应该插入允许使用超类型的灵活类型值。