This looks interesting. In converting this to work with WPF I ran into a couple of bumps. Obviously WPF doesn't have a single pattern of composition, so the abstract class is less useful. But a more worrying problem arrived when I tried to add
do! to the computation expression builder. This code works fine:open System.Windows
open System.Windows.Controls
[<AbstractClass>]
type IComposableControl<'a> when 'a :> FrameworkElement () =
abstract Control : 'a
abstract Bind : FrameworkElement * (FrameworkElement -> 'a) -> 'a
member this.Return (e: unit) = this.Control
member this.Zero () = this.Control
type WindowBuilder() =
// Using type inference IComposableControl<_> causes Error: anonymous type variables are not permitted in this declaration.
inherit IComposableControl<Window>()
let win = Window(Topmost=true)
override this.Control = win
override this.Bind(c: FrameworkElement, body) =
win.Content <- c
body c
type PanelBuilder(panel: Panel) =
inherit IComposableControl()
override this.Control = panel
override this.Bind(c: FrameworkElement, body) =
panel.Children.Add(c) |> ignore
body c
let win =
WindowBuilder()
{ let! panel =
PanelBuilder(StackPanel())
{ let! btn1 = Button(Content = "Hello")
let! btn2 = Button(Content = "World")
return () }
return () }
win.Show() // Pops up the window in FSI.
In trying to add
do! I get an overload error:[<AbstractClass>]
type IComposableControl<'a> when 'a :> FrameworkElement () =
abstract Control : 'a
[<OverloadID("1")>]
abstract Bind : FrameworkElement * (FrameworkElement -> 'a) -> 'a
[<OverloadID("2")>]
abstract Bind : FrameworkElement * (unit -> 'a) -> 'a
member this.Return (e: unit) = this.Control
member this.Zero () = this.Control
Error: The method 'Bind' is overloaded. Possible matches are shown below (or in the Error List window)
It seems that the type inference can't figure out which Bind method to use. I also noticed that there were no warnings generated when I used incorrect OverloadIDs on the derived builders.
I could not seem to resolve this error. Am I getting the syntax wrong here? Otherwise a verification would be useful.
thanks,
Danny
Hi Danny:
I'm floundering too. Not very familiar with type constraints, especially when combined with computation builders and abstract classes. Not too sure about how you expect to bind things with (unit -> 'a), so I changed it to (IComposableControl->'b), in keeping with the original. Here's what I came up with, but it generates a couple of internal compiler errors (see below):
And the errors:
Error 1 internal error: dest_typar_typ: not a typar type (Failure) Please build a small example that reproduces this problem and report it to fsbugs@microsoft.com. script2.fsx 31 6 Miscellaneous Files
Error 2 internal error: dest_typar_typ: not a typar type Please build a small example that reproduces this problem and report it to fsbugs@microsoft.com. script2.fsx 1 1 Miscellaneous Files
I'm floundering too. Not very familiar with type constraints, especially when combined with computation builders and abstract classes. Not too sure about how you expect to bind things with (unit -> 'a), so I changed it to (IComposableControl->'b), in keeping with the original. Here's what I came up with, but it generates a couple of internal compiler errors (see below):
#r "WindowsBase.dll"
#r "PresentationCore.dll"
#r "PresentationFramework.dll"
open System.Windows
open System.Windows.Controls
[<AbstractClass>]
type IComposableControl<'a> when 'a :> FrameworkElement () =
abstract Control : 'a
[<OverloadID("1")>]
abstract Bind : FrameworkElement * (FrameworkElement -> 'a) -> 'a
[<OverloadID("2")>]
abstract Bind : IComposableControl<'b> * (FrameworkElement -> 'a) -> 'a
member this.Return (e: unit) = this.Control
member this.Zero () = this.Control
type WindowBuilder() =
inherit IComposableControl<Window>()
let win = Window(Topmost=true)
override this.Control = win
[<OverloadID("1")>]
override this.Bind(c: FrameworkElement, body) =
win.Content <- c
body c
[<OverloadID("2")>]
override this.Bind(c: IComposableControl<'b>, body) : Window =
win.Content <- c.Control
body c.Control
type PanelBuilder(panel: Panel) =
inherit IComposableControl()
override this.Control = panel
[<OverloadID("1")>]
override this.Bind(c: FrameworkElement, body) =
panel.Children.Add(c) |> ignore
body c
[<OverloadID("2")>]
override this.Bind(c: IComposableControl<'b>, body) : Panel =
panel.Children.Add(c.Control) |> ignore
body c.Control
let win =
WindowBuilder()
{ let! panel =
PanelBuilder(StackPanel())
{ let! btn1 = Button(Content = "Hello")
let! btn2 = Button(Content = "World")
return () }
return () }
win.Show() // Pops up the window in FSI.
And the errors:
Error 1 internal error: dest_typar_typ: not a typar type (Failure) Please build a small example that reproduces this problem and report it to fsbugs@microsoft.com. script2.fsx 31 6 Miscellaneous Files
Error 2 internal error: dest_typar_typ: not a typar type Please build a small example that reproduces this problem and report it to fsbugs@microsoft.com. script2.fsx 1 1 Miscellaneous Files
Brian @ fsbugs replies with the following. Tested as working. Thanks Brian!
Thanks for the report; the internal error has been fixed in our internal development bits, and I expect the code below may work on Beta1 (haven’t tried it there). The main change I made is just being more explicit in the type signatures.
#if INTERACTIVE
#r "WindowsBase.dll"
#r "PresentationCore.dll"
#r "PresentationFramework.dll"
#r "System.Xaml"
#endif
open System
open System.Windows
open System.Windows.Controls
[<AbstractClass>]
type IComposableControl<'a when 'a :> FrameworkElement> () =
abstract Control : 'a
abstract Bind : FrameworkElement * (FrameworkElement -> 'a) -> 'a
abstract Bind : IComposableControl<'b> * (FrameworkElement -> 'a) -> 'a
member this.Return (e: unit) = this.Control
member this.Zero () = this.Control
type WindowBuilder() =
inherit IComposableControl<Window>()
let win = Window(Topmost=true)
override this.Control = win
override this.Bind(c: FrameworkElement, body: FrameworkElement -> Window) : Window =
win.Content <- c
body c
override this.Bind(c: IComposableControl<'b>, body: FrameworkElement -> Window) : Window =
win.Content <- c.Control
body c.Control
type PanelBuilder(panel: Panel) =
inherit IComposableControl()
override this.Control = panel
override this.Bind(c: FrameworkElement, body: FrameworkElement -> Panel) : Panel=
panel.Children.Add(c) |> ignore
body c
override this.Bind(c: IComposableControl<'b>, body: FrameworkElement -> Panel) : Panel=
panel.Children.Add(c.Control) |> ignore
body c.Control
let win =
WindowBuilder()
{ let! panel =
PanelBuilder(StackPanel())
{ let! btn1 = Button(Content = "Hello")
let! btn2 = Button(Content = "World")
return () }
return () }
win.Show() // Pops up the window in FSI.
#if COMPILED
[<STAThread()>]
do
let app = new Application() in
app.Run() |> ignore
#endif
Topic tags
- f# × 3660
- compiler × 263
- functional × 199
- c# × 119
- websharper × 114
- classes × 96
- web × 94
- book × 84
- .net × 82
- async × 72
- parallel × 43
- server × 43
- parsing × 41
- testing × 41
- asynchronous × 30
- monad × 28
- ocaml × 26
- tutorial × 26
- haskell × 25
- workflows × 22
- html × 21
- linq × 21
- introduction × 19
- silverlight × 19
- wpf × 19
- fpish × 18
- collections × 14
- pipeline × 14
- templates × 12
- monads × 11
- opinion × 10
- reactive × 10
- plugin × 9
- scheme × 9
- sitelets × 9
- solid × 9
- basics × 8
- concurrent × 8
- deployment × 8
- how-to × 8
- python × 8
- complexity × 7
- javascript × 6
- jquery × 6
- lisp × 6
- real-world × 6
- workshop × 6
- xaml × 6
- conference × 5
- dsl × 5
- java × 5
- metaprogramming × 5
- ml × 5
- scala × 5
- visual studio × 5
- formlets × 4
- fsi × 4
- lift × 4
- sql × 4
- teaching × 4
- alt.net × 3
- aml × 3
- enhancement × 3
- list × 3
- reflection × 3
- blog × 2
- compilation × 2
- computation expressions × 2
- corporate × 2
- courses × 2
- cufp × 2
- enterprise × 2
- entity framework × 2
- erlang × 2
- events × 2
- f# interactive × 2
- fsc × 2
- google maps × 2
- html5 × 2
- http × 2
- interactive × 2
- interface × 2
- iphone × 2
- iteratee × 2
- jobs × 2
- keynote × 2
- mvc × 2
- numeric × 2
- obfuscation × 2
- oop × 2
- packaging × 2
- pattern matching × 2
- pipelines × 2
- rx × 2
- script × 2
- seq × 2
- sockets × 2
- stm × 2
- tcp × 2
- trie × 2
- type × 2
- type provider × 2
- xna × 2
- zh × 2
- .net interop × 1
- 2012 × 1
- abstract class × 1
- accumulator × 1
- active pattern × 1
- addin × 1
- agents × 1
- agile × 1
- android × 1
- anonymous object × 1
- appcelerator × 1
- architecture × 1
- array × 1
- arrays × 1
- asp.net 4.5 × 1
- asp.net mvc × 1
- asp.net mvc 4 × 1
- asp.net web api × 1
- aspnet × 1
- ast × 1
- b-tree × 1
- bistro × 1
- bug × 1
- camtasia studio × 1
- canvas × 1
- class × 1
- client × 1
- clojure × 1
- closures × 1
- cloud × 1
- cms × 1
- coding diacritics × 1
- color highlighting × 1
- combinator × 1
- confirm × 1
- constructor × 1
- continuation-passing style × 1
- coords × 1
- coursera × 1
- csla × 1
- css × 1
- data × 1
- database × 1
- declarative × 1
- delete × 1
- dhtmlx × 1
- discriminated union × 1
- distance × 1
- docs × 1
- documentation × 1
- dol × 1
- domain × 1
- du × 1
- duf-101 × 1
- eclipse × 1
- edsl × 1
- em algorithm × 1
- emacs × 1
- emotion × 1
- error × 1
- etw × 1
- euclidean × 1
- event × 1
- example × 1
- ext js × 1
- extension methods × 1
- extra × 1
- facet pattern × 1
- fantomas × 1
- fear × 1
- float × 1
- fp × 1
- frank × 1
- fsdoc × 1
- fsharp.core × 1
- fsharp.powerpack × 1
- fsharpx × 1
- function × 1
- functional style × 1
- gc × 1
- generic × 1
- geometry × 1
- getlastwin32error × 1
- google × 1
- group × 1
- hash × 1
- history × 1
- hosting × 1
- httpcontext × 1
- https × 1
- hubfs × 1
- ie 8 × 1
- if-doc × 1
- inheritance × 1
- installer × 1
- interpreter × 1
- io × 1
- ios × 1
- ipad × 1
- kendo × 1
- learning × 1
- licensing × 1
- macro × 1
- macros × 1
- maps × 1
- markup × 1
- marshal × 1
- math × 1
- metro style × 1
- micro orm × 1
- minimum-requirements × 1
- multidimensional × 1
- multithreading × 1
- mysql × 1
- mysqlclient × 1
- nancy × 1
- nested × 1
- nested loops × 1
- node × 1
- object relation mapper × 1
- object-oriented × 1
- offline × 1
- option × 1
- orm × 1
- osx × 1
- owin × 1
- paper × 1
- parameter × 1
- performance × 1
- persistent data structure × 1
- phonegap × 1
- pola × 1
- powerpack × 1
- prefix tree × 1
- principle of least authority × 1
- programming × 1
- projekt_feladat × 1
- protected × 1
- provider × 1
- ptvs × 1
- quant × 1
- quotations × 1
- range × 1
- raphael × 1
- razor × 1
- rc × 1
- real-time × 1
- reference × 1
- restful × 1
- round table × 1
- runtime × 1
- scriptcs × 1
- scripting × 1
- service × 1
- session-state × 1
- sitelet × 1
- stickynotes × 1
- stress × 1
- strong name × 1
- structures × 1
- tdd × 1
- template × 1
- tracing × 1
- tsunamiide × 1
- type inference × 1
- type providers × 1
- upload × 1
- vb × 1
- vb.net × 1
- vector × 1
- visual f# × 1
- visual studio 11 × 1
- visual studio shell × 1
- visualstudio × 1
- web api × 1
- webapi × 1
- windows 8 × 1
- windows-phone × 1
- winrt × 1
- xml × 1
|
Copyright (c) 2011-2012 IntelliFactory. All rights reserved. Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us |
Built with WebSharper |
Not sure if this is linked anywhere else on hubFS, but IMHO really worth the double post!