2011-02-27 21 views
2

嗨,我需要幫助理解爲什麼我在這段代碼中得到一個值限制錯誤,以及如果可能的話我怎樣才能解決它。標準ml值限制錯誤

特別是在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 
+0

我認爲這個鏈接:http://users.cis.fiu.edu/~smithg/cop4555/valrestr.html應該給你一個想法,爲什麼您的代碼不工作。我不確定,但在我看來,如果將[val cnil:'列表]更改爲[val cnil:unit - >'列表](並相應地重寫實現),編譯器將停止抱怨。 –

回答

1

有兩個問題與您的代碼。一個是值限制錯誤,你可以通過改變

val cnil : 'a clist 

val cnil : unit -> 'a clist 

val cnil = 

fun cnil() = 

第二個問題解決是CNIL似乎沒有做任何事情 - perh aps是因爲頭部函數返回空而不是提高空值,並且使它變爲冗餘? Basis Library中已經有一個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