Flexible type currying in F #

A small piece of code to highlight the problem:

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!

Can someone explain why the behavior of the compiler is so different in the last two lines? And why did we lose information (about flexibility #Stream) in a function test_currying?

+5
source share
1 answer

It looks like a mistake to me. The compiler handles differently functions built using letand functions written as 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

( 14.4.2, (?) ), , , .

+3

All Articles