标准 ML/CML 错误运算符 - 操作数错误

发布于 2024-10-19 08:28:53 字数 1349 浏览 1 评论 0原文

我正在尝试使用标准 ML 的 CML 扩展来实现并发列表,但我遇到了错误,这可能与我是标准 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}

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}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

盗琴音 2024-10-26 08:28:53

所以你的问题在于你对 clist 的定义,

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

这意味着请求通道接受 'a 请求并回复 'a 。这与您的实现不一致。当您在通道上发送 CONS x 请求时,您是在说将 'a 类型的 x 添加到列表中,但是当您发送HEAD 请求,你是说把整个列表还给我。因此,CONS 请求应采用 'a,而 HEAD 请求应返回 'a 列表。您可以通过将 clist 定义更改为来解决问题。

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

我还建议将 cnil 定义更改为 unit -> 'a clist 函数,这样您就可以创建不同的并发列表。

例如:

val l1 = Clist.cnil()  
val l2 = Clist.cnil() (*cons'ing onto l2 won't affect l1*)

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*)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文