【问题标题】:Standard ML / CML wrong operator - operand error标准 ML/CML 错误运算符 - 操作数错误
【发布时间】:2023-03-30 18:01:01
【问题描述】:

我正在尝试使用标准 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}

【问题讨论】:

  • CLIST 签名在哪里?这是您遇到的类型错误,因此最好让它们可用。主要问题是您的“头部”操作不会解构我猜的列表。
  • 我刚刚重新粘贴了错误部分,因为我使用的是注释掉的文件并且行错误。我还包括了签名

标签: concurrency sml smlnj ml


【解决方案1】:

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

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

这表示请求通道接受'a 的请求并以'a 回复。这与您的实现不一致。当您在频道上发送CONS x 请求时,您是说将'a 类型的x 添加到列表中,但是当您发送HEAD 请求时,您是说将整个列表还给我。因此,CONS 请求应采用'aHEAD 请求应返回'a list。您可以通过将 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*)

【讨论】:

  • 您对问题的解释似乎是正确的,但您提出的解决方案对我来说似乎是错误的。当然正确的解决方法是让HEAD 只返回列表的头部?这就是名称HEAD 所暗示的含义,它也被hd 定义为HEAD 所暗示。 (请注意,为了匹配签名,hd 必须具有 'a clist -> 'a 类型。如果 recv replyCh 具有 'a list 类型,则不会发生这种情况。)
猜你喜欢
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多