Snažím sa vytvoriť grafickú aplikáciu vo F # pomocou pozorovateľných. Kód, ktorý mám zatiaľ, je:
open System.Windows.Forms
let form = new Form(Text="Test", TopMost=true)
let buttonNum0 = new Button(Text="1");
let buttonNum1 = new Button(Text="2", Top=20);
let buttonNum2 = new Button(Text="3", Top=40);
let buttonNum3 = new Button(Text="4", Top=60);
form.Controls.AddRange [| buttonNum0 ; buttonNum1; buttonNum2; buttonNum3 ; |]
let rec loop observable list = async{
printList list
(Async.Await)
let! somethingObservable = Async.AwaitObservable(observable)
match somethingObservable with
| 0 -> return! loop observable ("0"::list)
| 1 -> return! loop observable ("1"::list)
| 2 -> return! loop observable ("2"::list)
| 3 -> return! loop observable ("3"::list)
| _ -> return! loop observable ("?"::list)
}
module GUIInterface =
//Here we define what we will be observing (clicks)
let observables =
Observable.merge
<| Observable.map (fun _-> 0) GUI.buttonNum0.Click
<| Observable.map (fun _-> 1) GUI.buttonNum1.Click
<| Observable.map (fun _-> 2) GUI.buttonNum2.Click
<| Observable.map (fun _-> 3) GUI.buttonNum3.Click
Async.StartImmediate(loop GUIInterface.observables []) ; System.Windows.Forms.Application.Run(GUI.form)
Skúšal som používať viac či menej pozorovateľných akeď použijem iba dve z nich (pre skúšku 0 a 1), potom to funguje dobre. Môže Observable.merge používať iba 2 pozorovateľné položky? Existuje lepší spôsob, ako to urobiť, alebo ako môžem použiť niekoľko pozorovateľov?
S mojimi priemernými schopnosťami vyhľadávania som hľadalinternet pre niektoré návody a referencie, ktoré jednoduchým spôsobom vysvetľujú pojem pozorovateľných, reakčné funkčné programovanie, .net a WinForms. Ak máte nejaké odkazy na dobré stránky, rád by som ich mal. (Skúsený msdn (možno nie jeho správna časť?) A http://fsharpforfunandprofit.com/posts/concurrency-reactive)
odpovede:
0 pre odpoveď č. 1Nie ste si istí, prečo by váš kód nefungoval (myslím)že to nie je syntaktická analýza vašej syntaxe tak, ako to očakávate - použite radšej zátvorky ako backpipe, aby bolo poradie ops jasnejšie), ale v mojom kóde to funguje:
let btns = [GUI.buttonNum0; GUI.buttonNum1; GUI.buttonNum2; GUI.buttonNum3]
let observables = btns |> List.mapi(fun i btn -> Observable.map (fun _ -> i) btn.Click)
Observable.Merge observables
0 pre odpoveď č. 2
Po ďalšom rozvoji mojich schopností som prišiels ďalším riešením tohto problému. Pri použití FSharp.Control môžete zlúčiť dva pozorovateľné do jedného a potom tento proces zopakovať. Preto som prišiel na riešenie, ktoré som použil. Pomocou rekurzie môžete prebehnúť pozorovateľné veci, ktoré som sa rozhodol zaradiť do zoznamu, a najprv dať prvé dve dohromady, potom sumu s nasledujúcou a tak ďalej.
Alternatívna odpoveď:
let obsList = [ for x in 0..80 -> (Observable.map (fun _-> x) ((Array.get(gameButtons)(x)).Click)) ]
let rec obsMerger obsList =
match obsList with
| x1::[] -> x1
| x1::xs -> Observable.merge x1 (obsMerger xs)
| [] -> failwith "No Observables"