I was trying to define a more general case for the (!) operator as follows,
let inline (!) (cell : ^a) =
(^a : (member Value : ^b) cell)
So that it not only works for ref
type, but any type with a Value
member.
> !(ref 10) ;;
val it : int = 10
> !(lazy 5) ;;
val it : int = 5
But problem arises when I try to apply it to a type with type variables,
> let getValue (c : 'a ref) = !c ;;
let getValue (c : 'a ref) = !c ;;
------------------^^
C:\Users\User\AppData\Local\Temp\stdin(6,19): warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'obj'.
val getValue : c:obj ref -> obj
while it works fine if I expand the inline function.
> let getValue (c : 'a ref) = c.Value ;;
val getValue : c:'a ref -> 'a
Anyone knows why this happens? Thanks.
Since your getValue
function is not inline, the constraints won't work.
The problem is that the .NET type system can't store the type of constraints that F# can use in inline
.
As a result, when you have a non-inline function which uses an inline function in this way, you get an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With