![]() |
Edit |
![]() |
|
![]() |
Recent Changes |
![]() |
Subscriptions |
![]() |
Lost and Found |
![]() |
Find References |
![]() |
Rename |
| Search |
![]() |
List all versions |
By Don Syme, on the F# mailing list
One of the tricks I’ve been using a lot lately is the use of interactive windows to increase my productivity while using F# Interactive. I use these windows to display data and animate the interior state of algorithms I’m developing. I thought I’d send around a few of the code snippets that I use frequently, as I suspect others may find them useful too.
Firstly, to create a window interactively I just use:
open System.Drawing open System.Windows.Forms let form = new Form();; form.Visible <- true;; form.TopMost <- true;;
I then typically populate the window with a RichTextBox:
let rb = new RichTextBox();; form.Controls.Add(rb);; rb.Dock <- DockStyle.Fill;;
and set the font and color of the box and size of the form:
rb.ForeColor <- Color.DarkBlue;;
rb.Font <- new Font("Lucida Console",12.0f,FontStyle.Bold) ;;
form.Size <- new Size(400,600);;
I then create functions for viewing data using the ‘any_to_string’ polymorphic formatting function:
let view inp = rb.Text <- any_to_string inp;
which leads to a polymorphic viewer:
view "hello";; view ["hello"; "world"];; (1,2,3) |> view;; Array.create 100 (1,2,3) |> view;;
I’ll often use these as a quick hack in the middle of an algorithm to display the current state, or just before a failure point representing an unfinished case.
These sorts of techniques works particularly well from Visual Studio or an Emacs session where you have key bindings set up to automatically send text to an interactive FSI session, as it means you really don’t end up looking at the command-line top level at all, but rather see the results of computations in helper windows positioned at your will. If you’re using FSI a lot in a data-mode you might like to play with these techniques and customize them. For example, you can fit the structured text to a page by setting the print width options used by any_to_string:
let any_to_string_ex opts x = x |> any_to_layout opts |> layout_to_string opts
let view x =
let opts= { format_options.Default with printWidth = form.Width/16 } in
rb.Text <- any_to_string_ex opts x;;
Julian Laugel adds: In the same vein, we could also build on-the-fly guis with a basic listbox and a Go button :
open System
open System.Drawing
open System.Windows.Forms
let f= new Form();;
f.Visible <- true;;
f.TopMost <- true;;
let rb = new RichTextBox();;
f.Controls.Add(rb);;
let lb = new ListBox();;
f.Controls.Add(lb);
lb.Bounds <- new Rectangle(0,100,100,100);;
let bt = new Button();;
f.Controls.Add(bt);;
bt.Bounds <- new Rectangle(0,200,100,20);;
bt.Text <- "Go";;
// fill the list with a string array
let pop_list array = Array.iter (fun x->ignore(lb.Items.Add(x))) array ;;
let view inp = rb.Text <- any_to_string inp;;
// then choose your weapon : any function that operates on your item
let unuseful_function s = s ^ " is a good string";;
do bt.add_Click (new EventHandler ( fun _ _ ->
view ( unuseful_function((lb.SelectedItems.Item(0)).ToString())) ) );;
pop_list [|"hello" ; "world"|];;
The idea is to use it with an array of type (my_type.identifier , my_type.array_of_float_for_example ) : you get the index of the array of type with selectedIndex instead of selectedItems, you get the corresponding array_of_float, and you apply your function). The next natural step (for those involved in quant finance for example) in using a graphic output (see FSharpCharting) instead of textbox output .
![]() |
| This site supports the new NoFollow anti-spam initiative. |
Recent Topics