Type F # Providers and INPC Metaprogramming

I read the following article

http://studentguru.gr/b/kron/archive/2012/09/26/c-template-metaprogramming-and-f-type-providers.aspx

which shows a way to make Fibonacci compilation sequence generation times with F # type providers. The solution is in the article, but the final program

> cat .\fib.fs type fib = Playground.StaticFibonacci<100000> printfn "Fibonacci(100000) has %d digits" fib.Value.Length > fsc .\fib.fs -o fib.exe -r:.\FibonacciTypeProvider.dll –nologo > .\fib.exe Fibonacci(100000) has 20899 digits 

This look is very powerful. I was wondering if it is possible to create a type provider for INPC (INotifyPropertyChanged) so that instead

 open System.ComponentModel type MyObject() = let mutable propval = 0.0 let propertyChanged = Event<_, _>() interface INotifyPropertyChanged with [<clievent>] member x.PropertyChanged = propertyChanged.Publish member this.MyProperty with get() = propval and set(v) = propval <- v propertyChanged.Trigger(this, new PropertyChangedEventArgs("MyProperty")) 

Perhaps you can write

 open System.ComponentModel type MyObject() = let mutable propval = 0.0 let propertyChanged = Event<_, _>() interface INotifyPropertyChanged with [<clievent>] member x.PropertyChanged = propertyChanged.Publish member this.MyProperty : INPCTypeProvider<double> 

So, before I spend half a day so that maybe someone even more informed can tell me that I am wasting my time and this level of metaprograms is simply impossible.

+4
source share
1 answer

I do not think that you can achieve this with providers like F # (but I see that it would be good). There are a number of problems and thoughts that I can think of:

  • In your example, your INPCTypeProvider<double> will have to return something like a "property" view. This is not possible because properties are not first-class values ​​(as opposed to events). If they were, you don’t need a provider like ...

  • A type provider cannot be parameterized by an existing type, so you cannot write say:

     type MyNotifyObject = ProvideNotifiable<MyObject> 

    If possible, ProvideNotifiable can be a provider that accepts a type and creates a new type with an additional interface implementation. But at the moment this is not possible.

  • If you need only simple types, you can create something like:

     type MyObject = ProvideNotifiable<"MyProperty:int, OtherProperty:string"> 

    This can generate a type with two properties (defined in the string), but you cannot add anything else to the generated type (although you can probably generate the actual type using the generator provider and inherit it ...) I think this, probably the best you can do.

Besides type providers, you can simplify the implementation of INotifyPropertyChanged using quotes. This F # snippet gives a simple example that makes the implementation more secure.

+6
source

All Articles