3
votes

I have the following problem:

Within my type provider, I need to extend a generic type, that I have previously defined, with a method that will return an instance of this generic type. What I mean is, let's say we have :

type receiveType<'a> = class
   val Next:int
   val Type:string
   new (state,stateType) =
      {Next = state;Type = stateType;}                    
   end

later within my typeprovider I want to extend the type with the following function:

[<TypeProvider>] 
type ProviderTest() as this= (
   inherit TypeProviderForNamespaces() 
   let ns = "typeProviderTest.Provided"    
   let asm = Assembly.GetExecutingAssembly()

   let makeAType (s:string) =
      let typage =
         ProvidedTypeDefinition(asm, ns, s, Some typeof<obj>) 
      typage

   type receiveType<'a> with
      member this.receive(hey:'a,next:string)= 
         // generate a type from a string for instance
         // "hello" -> type helloType
         generateTypeFromString(next) 
        // let typage = ProvidedTypeDefinition(asm, ns, next, Some typeof<obj>)
        new receiveType<nextType>(5,"hello")   

The goal here for me is to generate an instance of the type receiveType<TypeHello> , iterate through a structure (Finite State Machine) to get the next possible message I can receive ( for instance "goodMorning"), create the type associated ( TypeGoodMorning ) and then generate an instance of receiveType<TypeGoodMorning>.

Thank you.

Do you mean to say that you want to create a function that would return values of different types on every call?Fyodor Soikin
In a way yes. But I want to generate the type of the value, to be returned on every call, from a string. Which means for a specific call of the function, with the string "Hello" for instance as an argument, I want to generate the type HelloType and return a value of type receiveType<HelloType>Leleutch
In a statically typed language, you can't make a function that has different return type depending on the argument value. This would defeat the whole idea of static typing: being able to verify program correctness before execution.Fyodor Soikin
Thank you for your answer. I would however want to ask you something. Let's say that I want to use this code to implement a protocol of communication. For instance I am a user that have the following code : channel.send(Hello()).receive(something)' this something` that I receive, I want it to be of type Response so that I can be sure that the one I speak with sends me a message of type Response and then follows the protocol. Thus,receive() needs an argument of type Response. Therefore, the only way would be to have Response type statically defined? Thank you again for your time.Leleutch