Version française
Home     About     Download     Resources     Contact us    
Browse thread
"Ref" and copy of functions
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Zheng Li <li@p...>
Subject: Re: "Ref" and copy of functions
 
Hi,  "Pierre-Evariste Dagand" <pedagand@gmail.com> writes: > 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 :  I 
don't understand what "arrow" is and the rational behind it, so 
don't take my suggestion seriously.   > type ('a,'b) arrow = Arrow 
of ( 'a -> 'b ) > let arr f = Arrow ( f ) > val arr : ('a -> 'b) 
-> ('a, 'b) arrow > let (>>>) (Arrow f) (Arrow g) =Arrow ( fun  c 
-> g  ( f  c ) ) > 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 >     ) > 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 > 
let run (Arrow f) input = >   f  input  At least on this 
particular example, you can use the following encoding (I 
deliberately use rectypes here, but you can always use extra 
variant instead)

---definition---
 
(* Only in mind: type ('a,'b) arrow = 'a -> 'b * ('a, 'b) arrow;; 
*)

let rec arr f x = f x, arr f;;

let rec (>>>) f g x = 
  let rf,nf = f x in let rg,ng = g rf in
  rg, nf >>> ng;;

let rec loop init f x =
  let ((init', r), n) = f (init,x) in
  r, loop init' n;;

let rec run f = function
  | [] -> []
  | h::t -> let r,n = f h in r :: run n t;;

---test---

let arr_counter = loop 0 (arr (fun (c,x) -> c+1,c+x));;

let arr_double = arr (( * ) 2);;

let arr_my_small_arrow = arr_counter >>> arr_double;;

run arr_my_small_arrow [6;5;4;3];;
- : int list = [12; 12; 12; 12]
 
Since it doesn't use mutable variable, it's free to make copy.   > 
P.S.: For those who are just curious, these combinators are used 
in a > functional-reactive library for Peer-to-Peer overlays 
programming.   It looks like "arrow" is for some kind of flow-like 
programming, then you may also take a look at SDFlow [1]. Your 
example can be encoded in a point-free style as 

---flow---
 
let arr_counter = 
  comb |- map (fun (x,c) -> x+c,c+1) |- split |> curry |- 
  feedr[<'0>];;

let arr_double = map (( * ) 2);;

let arr_my_small_arrow = arr_counter |- arr_double;;

arr_my_small_arrow [<'6;'5;'4;'3>] |> to_list;;
- : int list = [12; 12; 12; 12]

Note however, SDFlow is just a proof of concept. The syntax on 
recursion can be made much more straightforward with some camlp4 
script to allow recursive value with preconditions. I just don't 
have time to do that. 

HTH.

-- 
Zheng Li
http://www.pps.jussieu.fr/~li