Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# Calling inline function with type variables

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.

like image 662
Doaz Avatar asked Jun 18 '16 00:06

Doaz


1 Answers

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.

like image 67
John Palmer Avatar answered Nov 18 '22 06:11

John Palmer