Browse thread
"Ref" and copy of functions
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Pierre-Evariste Dagand <pedagand@g...> |
| Subject: | "Ref" and copy of functions |
Hi Caml-list,
I'm looking for advices about a "clean way" of doing something which,
by design, isn't. So, let states the problem.
I'm doing a combinator library based on Arrows for a Yampa-like system :
type ('a,'b) arrow = Arrow of ( 'a -> 'b )
Thus, I can instantiate an arrow with :
let arr f = Arrow ( f )
val arr : ('a -> 'b) -> ('a, 'b) arrow
Then, I have, for example, the composition of arrows :
let (>>>) (Arrow f) (Arrow g) =Arrow ( fun c -> g ( f c ) )
val ( >>> ) : ('a, 'b) arrow -> ('b, 'c) arrow -> ('a, 'c) arrow
Right here, everything plays well (excepted some weak type variables
issues but that's not a big deal).
But (and that's here that the trouble is) I need a "loop" combinator,
that I wrote this way :
let loop init (Arrow f) =
let state = ref init in
Arrow (
fun c ->
let new_state , output = f ( !state , c ) in
state := new_state;
output
)
val loop : 'a -> ('a * 'b, 'a * 'c) arrow -> ('b, 'c) arrow
Finally, I can write a small arrow :
let arr_counter = loop 0 ( arr ( fun ( counter , x ) -> counter+1 ,
counter+x ) )
let arr_double = arr ( fun x -> 2*x )
let arr_my_small_arrow = arr_counter >>> arr_double
And I execute it with :
let run (Arrow f) input =
f input
val run : ('a, 'b) arrow -> 'a -> 'b
And it works. Right.
But now, I would like to be able to "copy" a built arrow and to be
able to execute the copy without side-effecting on the first one.
Obviously, I cannot do that in this implementation.
My current solution is really *ugly* :
let arrow_string = Marshal.to_string arrow [ Marshal.No_sharing ;
Marshal.Closures ]
Then I "Marshal.from_string arrow_string". I'm not even sure if it
will not blow out of my hands with "strange" things in the Ref cell.
I'm aware of implementations in CPS but I use to think that it has a
performance cost that I'm not ready to pay (I'm fighting against a C++
code so...).
So if someone knows an elegant solution to my problem (if someone has
read this mail until here), please let me know :-)
Best regards,
P.S.: For those who are just curious, these combinators are used in a
functional-reactive library for Peer-to-Peer overlays programming.
--
Pierre-Evariste DAGAND
http://perso.eleves.bretagne.ens-cachan.fr/~dagand/