Friday, September 12, 2008

A Stab at Hughes Arrows in F#

Well it's been awhile since I have posted. For one I 've been a bit bogged down with work. But that's another story that I might go into at a later date. What I wanted to blog about today is arrow. Some of you may be familiar with them. They are abstract constructs that can be very useful in things like animation or event driven programing. How did I go from Euler problems to abstract patterns?

Well it started with my love of video games. Since I like a lot I have hidden aspirations of being a game programmer. (Although to this date I have work only on one game which as far as I know never saw the light of day.) So I was looking into using functional programming techniques with game programming. (BTW there is an interesting journal here by a functional programmer.) So I started looking at animation. I came across an old paper about the Fran framework. It is based on the functional reactive (FR of Fran) programming. But that wasn't the interesting part. It is what this library spawned which is Yampa. Yampa makes extensive use of arrows. So my interest was piqued. I went to look for information on these arrows.

Through the use of the "Programming with Arrows" and "Directing JavaScript with Arrows", I was able to get a little bit of a hold on the concept of arrows. So with a dangerous amount of knowledge of arrows and F# I wrote this:


#light
module Arrow =
type Arrow<'inp, 'out> (f:'inp -> 'out) =
member a.run x = f x

let arr f = new Arrow<;'i,'o>(f)

let op_RightShift (f:Arrow<'inp,'mid>) (g:Arrow<'mid,'out>) =
arr (fun i -> g.run(f.run i))

let (&&&) (f:Arrow<'b,'c>;) (g:Arrow<'b,'d>) =
arr (fun i -> (f.run i, g.run i))

let first (f:Arrow<'a, 'b>) =
arr (fun (i,x) -> ( f.run i, x))

let second (f:Arrow<'a, 'b>) =
let swap (x,y) = (y,x)
(arr swap) >>> (first f) >>> (arr swap)

let ( *** ) (f:Arrow<'a,'b>) (g:Arrow<'c,'d>) =
(first f) >>> (second g)

I was surprised how quickly I was able to get this together. So what do you think? How can I improve it? What did I do wrong? All comments are welcome.

1 comment:

thinkhard said...

I came across your blog when searching google for Hughes Arrows for my blog series (http://blog.thinkhard.net), wondering if you're still doing F#? If you are, and you are not already in an F# user group you can join about 50 of us on freenode in the channel ##fsharp. If you don't have an IRC client handy, an easy way to connect is from my other site http://fpound.net/chat -- Hope to see you there sometime, Thedric :D