3

Standard ML の CML 拡張を使用して並行リストを実装しようとしていますが、おそらく Standard ML の初心者であることに関係しているエラーが発生しています。入力チャネルと出力チャネルを持つ clist を実装し、リストの状態をループに格納します。ただし、私のコードはコンパイルされず、以下のエラーが発生します

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

これは署名ファイルです

signature CLIST =
  sig
    type 'a clist

    val cnil : 'a clist
    val cons : 'a -> 'a clist -> 'a clist
    val hd : 'a clist -> 'a
  end

私が得ているエラー:

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}
4

1 に答える 1

0

だからあなたの問題はあなたの定義にありますclist

datatype 'a clist = CLIST of { reqCh : 'a request chan, replyCh : 'a chan }

これは、リクエスト チャネルが のリクエストを受け取り'a'a. これは実装と一致しません。CONS xチャネルでリクエストを送信するときは、リストにxタイプを追加すると言っていますが、リクエストを送信すると、リスト全体を返してくださいと言っています。したがって、リクエストは を受け取り、リクエストは を返す必要があります。定義を次のように変更することで問題を解決できます'aHEADCONS'aHEAD'a listclist

datatype 'a clist = CLIST of { reqCh : 'a request chan, replyCh : 'a list chan }

の定義を関数に変更することもお勧めしますcnilunit -> 'a clistこのようにして、別個の同時リストを作成できます。

例えば:

val l1 = Clist.cnil()  
val l2 = Clist.cnil() (*cons'ing onto l2 won't affect l1*)
于 2015-06-05T19:02:22.093 に答える