Why does bigint compile in one case and not in another?

I am just starting out with F #, and I found the behavior displayed below puzzling. Any explanation?

let bg = bigint 1;;
(* val bg : System.Numerics.BigInteger = 1 *)

let bg = (bigint) 1;;
(* error FS0041: A unique overload for method 'BigInteger' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: System.Numerics.BigInteger(value: byte []) : unit, System.Numerics.BigInteger(value: decimal) : unit, System.Numerics.BigInteger(value: float) : unit, System.Numerics.BigInteger(value: float32) : unit, System.Numerics.BigInteger(value: int) : unit, System.Numerics.BigInteger(value: int64) : unit, System.Numerics.BigInteger(value: uint32) : unit, System.Numerics.BigInteger(value: uint64) : unit *)
+4
source share
1 answer

This is due to overload. See, bigintit is actually a synonym for a class BigInteger, and applying it as a function translates into a constructor call, but which of several constructors depends on the type of argument.

This works great when you apply it as a function: the type of the argument is known, and the compiler can choose the appropriate overload. But if you try to consider it as a value function, the argument is absent, and the compiler does not know which overload to take.

Here's a simpler reprogramming:

type T() =
  member static f (s: string) = s
  member static f (i: int) = I

let a = T.f 1 // works
let b = T.f "abc" // works
let c = T.f // doesn't work: which `f` do you mean?

// possible workaround: create non-overloaded wrappers
let fStr (s: string) = T.f s
let fInt (i: int) = T.f i
let a = fStr // works fine
let b = fInt // works fine, too

: , . , . .


( )

: ", , ". , , :

// Original repro:
let a = (bigint) 5

// Same thing:
let f = bigint
let a = f 5

: , ; , .

+6

Source: https://habr.com/ru/post/1669210/


All Articles