Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Runtime coercion of generic types in F#

Tags:

.net

f#

I have a base class with explicit generic arguments in F#. I'm trying to check if the given type I'm using implements a specific interface. I thought "if ob :? ISysAware then" would do, but the complain is always the same:

let (|SysAware|_|) t = 
    match t with
    | :? ISysAware as p -> Some(p)
    | _ -> None

error FS0008: This runtime coercion or type test from type 'a to ISysAware involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed.

I'd prefer not to use reflection here, obviously. IsAssignableFrom would do the trick, at a high cost.

Thoughts?

like image 511
hammett Avatar asked Jan 26 '12 23:01

hammett


2 Answers

Some F# types are value types; adding box ensures that type test is performed on reference types only:

let (|SysAware|_|) t = 
    match box t with
    | :? ISysAware as p -> Some(p)
    | _ -> None
like image 87
pad Avatar answered Oct 29 '22 15:10

pad


The reason for the error is the type checker being confused as it can't work out the type, the solution - similar to pad's is to add a type annotation

let (|SysAware|_|) (t:obj) = 
    match t with
    | :? ISysAware as p -> Some(p)
    | _ -> None
like image 5
John Palmer Avatar answered Oct 29 '22 15:10

John Palmer