【OCaml】循环队列模块设计

最近由于项目需要,需要用OCaml语言去实现一个循环队列去实现一些功能。翻遍了Ocaml的官方网站和标准库,发现OCaml只提供普通的队列,于是自己基于Array模块设计了循环队列RoundRobinQueue的模块。

主要类型由array队列,对头队尾指针front和rear组成。

mli文件如下:

type 'a round_robin_queue2 = { queue : 'a array ; mutable front : int ; mutable rear : int };;
val create : int -> 'a -> 'a round_robin_queue2
val iter : ('a -> 'b) -> 'a round_robin_queue2 -> unit
val length : 'a round_robin_queue2 -> int
val get : 'a round_robin_queue2 -> int -> 'a option
val peek : 'a round_robin_queue2 -> 'a option
val clear : 'a round_robin_queulengthe2 -> unit
val copy : 'a round_robin_queue2 -> 'a round_robin_queue2
val enqueue : 'a round_robin_queue2 -> 'a -> unit
val transfer : 'a round_robin_queue2 -> 'a round_robin_queue2 -> unit
val dequeue : 'a round_robin_queue2 -> 'a option
val pfarray : ('a -> 'b) -> 'a round_robin_queue2 -> unit

突然发现csdn的markdown编辑器,竟然不识别ocaml语言,不能高亮显示。心态有点小崩……

具体函数实现代码我放在了我的资源当中,有需求的同学请自取。

模块测试代码如下:

open RoundRobinQueue

type data = { size : int ; time : float };;

type packet = { src : int ; port : int };;

let data1 ={ size =64 ; time =456.};;

let data2 ={ size =128 ; time =1234.};;

let packet1 ={ src =177667 ; port =6};;

let packet2 ={ src =166666 ; port =2};;

let pfdata a = print_string ("s:"^(string_of_int a.size)^ "t:"^(string_of_float a.time));;

let pfpacket a = print_string ("src:"^(string_of_int a.src)^ "port:"^(string_of_int a.port));;

let pfqueuedata f a =
	let elem = RoundRobinQueue.get a 8 in
	print_int (a.front);
	print_int (a.rear);
	print_string("-");
	print_int (length a);
	print_string("-");
	iter f a;
	
	match elem with
		None -> print_string("None");
	| Some data -> print_string ("Some "); f data;
			print_newline();
;;

let loop f sum =
	let rec loop1 f n =
		if n >= 0 then begin f(); loop1 f (n -1) end else () in
	loop1 f sum;;

let _ =
	let a = create 10 data1 in
	let loopq l d s = begin enqueue l d;
			pfqueuedata pfdata l	;
			print_newline(); end in
	let loopq1 l s = begin dequeue l ;
			pfqueuedata pfdata l	;
			print_newline(); end in
	(* pfqueuedata a; print_newline(); enqueue a data2; pfqueuedata a ;        *)
	(* print_newline(); dequeue a; pfqueuedata a ; print_int (10 mod 8)        *)
	loop (loopq a data2 ) 10;
	loop (loopq1 a) 10;
	let b = copy a in
	transfer a b;
	loop (loopq1 b) 10;
	loop (loopq b data2) 10;
;;

let _ =
	let a = create 10 packet1 in
	let loopq l d s = begin enqueue l d;
			pfqueuedata pfpacket l	;
			print_newline(); end in
	let loopq1 l s = begin dequeue l ;
			pfqueuedata pfpacket l	;
			print_newline(); end in
	(* pfqueuedata a; print_newline(); enqueue a data2; pfqueuedata a ;        *)
	(* print_newline(); dequeue a; pfqueuedata a ; print_int (10 mod 8)        *)
	loop (loopq a packet2 ) 10;
	loop (loopq1 a) 10;
	let b = copy a in
	transfer a b;
	loop (loopq1 b) 10;
	loop (loopq b packet2) 10;
;;

测试结果如下:

01-1-s:128t:1234.None
02-2-s:128t:1234.s:128t:1234.None
03-3-s:128t:1234.s:128t:1234.s:128t:1234.None
04-4-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
05-5-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
06-6-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
07-7-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
08-8-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
09-9-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.Some s:128t:1234.

10-9-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.Some s:128t:1234.

21-9-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.Some s:128t:1234.

31-8-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
41-7-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
51-6-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
61-5-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
71-4-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
81-3-s:128t:1234.s:128t:1234.s:128t:1234.None
91-2-s:128t:1234.s:128t:1234.None
01-1-s:128t:1234.None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
12-1-s:128t:1234.None
13-2-s:128t:1234.s:128t:1234.None
14-3-s:128t:1234.s:128t:1234.s:128t:1234.None
15-4-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
16-5-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
17-6-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
18-7-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
19-8-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.None
10-9-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.Some s:128t:1234.

21-9-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.Some s:128t:1234.

32-9-s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.s:128t:1234.Some s:128t:1234.

01-1-src:166666port:2None
02-2-src:166666port:2src:166666port:2None
03-3-src:166666port:2src:166666port:2src:166666port:2None
04-4-src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
05-5-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
06-6-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
07-7-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
08-8-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
09-9-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2Some src:166666port:2

10-9-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2Some src:166666port:2

21-9-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2Some src:166666port:2

31-8-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
41-7-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
51-6-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
61-5-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
71-4-src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
81-3-src:166666port:2src:166666port:2src:166666port:2None
91-2-src:166666port:2src:166666port:2None
01-1-src:166666port:2None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
11-0-None
12-1-src:166666port:2None
13-2-src:166666port:2src:166666port:2None
14-3-src:166666port:2src:166666port:2src:166666port:2None
15-4-src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
16-5-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
17-6-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
18-7-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
19-8-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2None
10-9-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2Some src:166666port:2

21-9-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2Some src:166666port:2

32-9-src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2src:166666port:2Some src:166666port:2


经过测试,模块能够实现原本标准库里Queue模块的大多数功能,满足基本的使用。

在设计模块的过程中,需要注意以下几点:

  • 设计一个mli时,要选择是提供类型的具体定义还是保持为抽象类型,大多数情况下正确地选择都是保持为抽象类型,这样可以提高设计的灵活性,模块使用可以确保不变式约束。
    抽象可以提高灵活性,通过限制用于与类型的交互,从而尽可能减少用户对实现细节的依赖。
  • 在写模块接口时,不只是要考虑那些读mli文件的人能够很容易地理解的接口,更重要的,对于那些读调用点代码的人,要让调用尽可能清晰。

猜你喜欢

转载自blog.csdn.net/qq_32350719/article/details/88795982