#light

type Arrow<'inp, 'out> (f:'inp ->; 'out) =

let func = f

member a.run x = func x

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

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

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)

type either<'a, 'b> =

| Left of 'a

| Right of 'b

let ( |.| ) (f: Arrow<'a, 'c>) (g:Arrow<'b, 'c>) =

arr (fun x -> match x with

| Left a -> f.run a

| Right b -> g.run b

)

let left (f: Arrow&<'a,'b>) =

arr (

fun x -> match x with

| Left a -> Left (f.run a)

| Right a -> Right a

)

let right (f: Arrow<'a, 'b>) =

let mirror = fun x -> match x with

| Left a -> Right a

| Right a -> Left a

(arr mirror) >.> left f >.> (arr mirror)

let ( +.+ ) (f: Arrow<'a,'b>) (g: Arrow<'c,'d>) = (left f) >.> (right g)

I have kind of gotten the loop combinator working, But it is a loop combinator combined with a delay function.

Well I guess next, it about time to explain some of this mess.