forki23
forki23

Reputation: 2814

Creating a list of a provided type in F#

I am trying to add a basic JSON type provider to fsharpx. At the moment I am struggeling with JSON Arrays. Consider the following test case:

type SimpleArray = JSON< "{\"items\":[{\"id\":\"Open\"},{\"id\":\"Pause\"}]}">

let a = SimpleArray()

[<Test>] 
let ``Can parse simple arrays``() = 
    a.items.[0].id
    |> should equal "Open"

    a.items.[1].id
    |> should equal "Pause"

The idea is that I want to use the first element in the array to get the type of the collection elements. Then I want to add a property "items" to the SimpleArray type that gives a list of this new type.

The code can be found in the github repo Github. The interesting part starts at line 38. As you can see the whole thing has to be recursive since the JArray could also contain nested JArrays.

| JArray list ->
    let newType = annotateAsJson list.[0] (runtimeType<obj> (ownerTy.Name + "_" + e.Key))
    ownerTy.AddMember newType
    Some(provideProperty
            e.Key
            newType // TODO: make this a list
            (fun args -> Expr.Coerce(<@@ (%%args.[0] : obj) @@>, newType)) // TODO: return the list
            :> MemberInfo)

Thanks, Steffen

Upvotes: 3

Views: 275

Answers (1)

kvb
kvb

Reputation: 55184

What's the question, exactly? It looks like you need to provide multiple types (e.g. in your example you've got the outer type containing items and then an inner type containing id). You probably want the inner type to be a nested type within the outer type. Then you make the provided items property contain a list of the inner type. Is there a particular aspect of that which you are having trouble with?

EDIT

If it's just that you are wondering how to create the Type instance itself, have you tried

typedefof<_ list>.MakeGenericType(newType)

This presumes that the underlying value it itself an obj list, which is necessary since newType erases to obj.

Upvotes: 3

Related Questions