Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

f# generic type comparison

Tags:

types

generics

f#

I'm trying to figure out if an obj returned from a call is of a certain type. Here is my code:

type MyType<'T>= 
    val mutable myArr : array
    val mutable id : int
    val mutable value : 'T

and in some method that has MyType in scope...

let a  = someFunThatReturnsObj()   // a could be of type MyType 

How do I figure out if a is of type MyType?

like image 334
PhilBrown Avatar asked Oct 19 '10 19:10

PhilBrown


2 Answers

match a with
| :? MyType<int> as mt -> // it's a MyType<int>, use 'mt'
| _ -> // it's not

If you care about just a MyType<X> for some unknown X, then

let t = a.GetType()
if t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<MyType<int>> then
    // it is
like image 79
Brian Avatar answered Sep 28 '22 06:09

Brian


I don't think this is that simple (remember I am f# naive) consider the follwoing scenario where

1) we are using generics on multiple types 2) we don't have the type information for an object so it comes in to a function as type obj, like in some of the .NET datacontract / serialization libraries

I reworked my proposal to use reflection:

type SomeType<'A> = { 
        item : 'A 
    } 


type AnotherType<'A> = { 
    someList : 'A list 
} 

let test() = 

    let getIt() : obj =  
        let results : SomeType<AnotherType<int>> = { item = { someList = [1;2;3] }} 
        upcast results 

    let doSomething (results : obj) =  
        let resultsType = results.GetType()
        if resultsType.GetGenericTypeDefinition() = typedefof<SomeType<_>> then 
            let method = resultsType.GetMethod("get_item")
            if method <> null then
                let arr = method.Invoke(results, [||]) 
                if arr.GetType().GetGenericTypeDefinition() = typedefof<AnotherType<_>> then 
                    printfn "match" 

    getIt() |> doSomething  

Seems like there should be more natural way of doing this...

like image 24
akaphenom Avatar answered Sep 28 '22 07:09

akaphenom