стандартные ошибки ограничения значения мл - PullRequest
2 голосов
/ 27 февраля 2011

Привет, мне нужна помощь, чтобы понять, почему я получаю ошибку ограничения значения в этом коде и как я могу ее исправить, если это возможно.

В частности, в val cnil я пытаюсь создать пустую структуру 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 *)
  val cnil =
    let
      val reqCh = channel()
      val replyCh = channel()
      fun loop l = case recv reqCh of
          CONS x =>
            (loop (x::l))
        | 
          HEAD => (let fun head (h::t) = h | head [] = Empty in send(replyCh, head(l)) end ; loop l)
    in
      spawn(fn () => loop nil);
      CLIST {reqCh = channel(), replyCh = channel() }
    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:10.7-22.5 Warning: type vars not generalized because of
   value restriction are instantiated to dummy types (X1,X2,...)
clist.sml:1.1-29.4 Error: value type in structure doesn't match signature spec
    name: cnil
  spec:   'a ?.Clist.clist
  actual: ?.X1 ?.Clist.clist

1 Ответ

1 голос
/ 04 марта 2011

Есть две проблемы с вашим кодом. Одним из них является ошибка ограничения значения, которую можно исправить, изменив

val cnil : 'a clist

до

val cnil : unit -> 'a clist

и

val cnil =

до

fun cnil () =

Вторая проблема заключается в том, что cnil, похоже, ничего не делает - возможно, потому, что функция head возвращает Empty, а не вызывает Empty, и вы сделали это избыточным? В Базисной библиотеке уже есть функция hd, которая делает это. Тип clist также не обязательно должен быть типом данных. Я думаю, что вы хотите, это:

structure Clist : CLIST =
struct
  open CML

  datatype 'a request = CONS of 'a | HEAD

  type 'a clist = { reqCh : 'a request chan, replyCh : 'a chan }

  (* create a clist *)
  fun cnil () =
    let
      val clist as {reqCh, replyCh} = {reqCh = channel(), replyCh = channel()}       
      fun loop l = case recv reqCh of
          CONS x =>     
            (loop (x::l))
        |                                     
          HEAD => (send(replyCh, hd l); loop l)
    in                        
      spawn(fn () => loop nil);
      clist
    end


  fun cons x (clist as {reqCh, replyCh})=
    (send (reqCh, CONS x); clist)

  fun hd (CLIST {reqCh, replyCh}) = (send (reqCh, HEAD); recv replyCh)
end
...