2011-07-17 13 views
3

我想知道爲什麼在Ocaml中,「let ..和...」沒有與「type ......然後......「:Ocaml中的「type ... and」和「let ... and」之間作用域的相互影響

如下因素之一是OK,T2在同一個作用域爲T1

# type t1 = t2 
and t2 = int;; 

這下面一個是錯誤的,在V2中不作用域

# let v1 = v2 
and v2 = 3;; 

    Characters 9-11: 
    let v1 = v2 
      ^^ 

Error: Unbound value v2 

即使「讓rec」不起作用...

# let rec v1 = v2 
and v2 = 3;; 

    Characters 13-15: 
    let rec v1 = v2 
       ^^ 
Error: This kind of expression is not allowed as right-hand side of `let rec' 

爲什麼在「type ... and」和「let ... and」之間作用域範圍的不一致?謝謝。

回答

9

類型是隱式遞歸的。如果你想與「let」有相同的效果,使用「let rec ..和」。

在理想的語言中,有意義的綁定形式應該有兩個版本,一個是遞歸的,一個是非遞歸的。在Caml,let就是這種情況,你有letlet rec。沒有可訪問的非遞歸類型綁定形式;它不一定是默認的,即使type nonrec ...也可以。這是Caml語法的缺陷;例如,給出了非遞歸類型定義的不良後果in this blog post

關於你的第二個例子,這不是關於範圍界定,而是某些遞歸定義的有效性而不是其他。這是一個完全正交的問題(請參閱ocaml manual遞歸定義是有效的),並且let rec完全按照您希望的方式在範圍內進行。

+1

類型隱含* equirecursive *。要獲得* isorecursive *類型,您需要在編譯器上使用'-ypeypes'標誌。這裏認爲的不一致只是語法上的一個瑕疵,它並不值得讓人失望。對於'let ...和... in ...'結構中的語言,並沒有真正需要類型的nonrec ...和...'構造。 –

+1

@james:我認爲你弄錯了,'-ypeypes'能夠實現equirecursivity(名字及其展開之間的平等),而標準的代數數據類型是isorecursives(同構,由構造函數介於名字和它的展開之間)。儘管(這個名稱在範圍中是可用的),但它與*範圍問題沒有任何關係。關於nonrec的問題,你有沒有看過我鏈接到的博客文章,這說明強制遞歸類型定義引起的真正煩惱? – gasche

+0

對於後人:'type nonrec'現在是一件事情。 –