Standard ML / CML wrong operator - operand error
I am trying to 开发者_运维问答implement a concurrent list using CML extensions of Standard ML but i am running into errors that are probably to do with my being a newbie in Standard ML. I have implemented the clist as having an input and output channel and I store the list state in a loop. However my code does not compile and gives errors below
structure Clist : CLIST =
struct
open CML
datatype 'a request = CONS of 'a | HEAD
datatype 'a clist = CLIST of { reqCh : 'a request chan, replyCh : 'a chan }
(* create a clist with initial contents l *)
val cnil =
let
val req = channel()
val reply = channel()
fun loop l = case recv req of
CONS x =>
(loop (x::l))
|
HEAD => (send(reply, l); loop l)
in
spawn(fn () => loop nil);
CLIST {reqCh=req,replyCh=reply}
end
fun cons x (CLIST {reqCh, replyCh})=
(send (reqCh, CONS x); CLIST {reqCh = reqCh, replyCh = replyCh})
fun hd (CLIST {reqCh, replyCh}) = (send (reqCh, HEAD); recv replyCh)
end
This is the signature file
signature CLIST =
sig
type 'a clist
val cnil : 'a clist
val cons : 'a -> 'a clist -> 'a clist
val hd : 'a clist -> 'a
end
Errors I am getting:
clist.sml:21.4-21.35 Error: operator and operand don't agree [circularity]
operator domain: {replyCh:'Z list chan, reqCh:'Z list request chan}
operand: {replyCh:'Z list chan, reqCh:'Z request chan}
in expression:
CLIST {reqCh=req,replyCh=reply}
So your problem is in your definition of clist
datatype 'a clist = CLIST of { reqCh : 'a request chan, replyCh : 'a chan }
This is saying that the request channel takes in a request of 'a
and replies with a 'a
. This is not consistent with your implementation. When you send a CONS x
request on the channel, you are saying add x
of type 'a
to the list, but when you send a HEAD
request, you are saying give me back the entire list. Thus, a CONS
request should take a 'a
and a HEAD
request should return a 'a list
. You can fix your problem by changing your clist
definition to
datatype 'a clist = CLIST of { reqCh : 'a request chan, replyCh : 'a list chan }
I would also suggest changing your definition of cnil
to a unit -> 'a clist
function, this way you can create distinct concurrent lists.
For example:
val l1 = Clist.cnil()
val l2 = Clist.cnil() (*cons'ing onto l2 won't affect l1*)
精彩评论