[Ur] Client-side programming style
Artyom Shalkhakov
artyom.shalkhakov at gmail.com
Fri Jan 22 00:24:46 EST 2010
Hello,
I wanted to create a list of something with a single focus point (that
is, one of the elements of a list would be "selected"), present this
to users, and let them "edit" it (that is, manipulate the selected
element, add and remove elements, and change their selection).
I decide to create a data structure which supports these operations
(following Xmonad). In this case, it would be the zipper of a list:
> con zipper t = {L: list t, F: t, R: list t}
The elements of a list, say 1 :: 2 :: 3 with 1 being focused, would be
something like
> {L=nil, F=1, R=2::3::nil}
We can move to the "right" and to the "left", which would change the
structure like this:
> {L=1::nil, F=2, R=3::nil} (* moved to the right: this shifts one element to the left *)
> {L=2::1::nil, F=3, R=nil} (* to the right once more *)
To move one step left would be the exact opposite, so we won't cover this here.
Here's the test page in full which uses the zipper:
> fun listeditor () =
> lst <- source (Zipper.mkzipper "foo");
> s <- source "";
> let
> fun app f = s' <- get s; l' <- get lst; set lst (f s' l')
> fun app2 f = l' <- get lst;
> case (f l') of
> None => return ()
> | Some x => set lst x
> fun showzipper (z: Zipper.zipper string): signal xbody = let
> val lst = List.mapX (fn x => <xml><li>{[x]}</li></xml>)
> in
> return <xml><ul>
> {lst (Zipper.left z)}
> <li><b>{[Zipper.focus z]}</b></li>
> {lst (Zipper.right z)}
> </ul></xml>
> end
> in
> return <xml><body>
> <label>Text: <ctextbox source={s}/></label>
> <dyn signal={l <- signal lst; showzipper l}/>
> <button onclick={app Zipper.consLeft} value="Insert text before"/>
> <button onclick={app Zipper.consRight} value="Insert text after"/>
> <button onclick={app2 Zipper.moveLeft} value="Move focus up"/>
> <button onclick={app2 Zipper.moveRight} value="Move focus down"/>
> <button onclick={app2 Zipper.deleteLeft} value="Delete and move focus up"/>
> <button onclick={app2 Zipper.deleteRight} value="Delete and move focus down"/>
> </body></xml>
> end
After looking at the example dlist module, I noticed that it was much
more elaborate. What is the reason for that? Also, I found that code
hard to follow; is there a nice metaphor or something to help making
sense out of that code?
I attached an implementation of list zipper in case anybody is interested.
Cheers,
Artyom Shalkhakov.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: zipper.ur
Type: application/octet-stream
Size: 1166 bytes
Desc: not available
URL: <http://www.impredicative.com/pipermail/ur/attachments/20100122/2be85cd8/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: zipper.urs
Type: application/octet-stream
Size: 663 bytes
Desc: not available
URL: <http://www.impredicative.com/pipermail/ur/attachments/20100122/2be85cd8/attachment-0001.obj>
More information about the Ur
mailing list