2014-11-09 43 views
0

這只是一個練習(我意識到下面提到的功能已經在List中實現)。以折線定義列表長度

假設我有一個包含以下行

val length : 'a list -> int 
val fold : init:'acc -> f:('acc -> 'a -> 'acc) -> 'a list -> 'acc 

接口......而我實現fold這樣的:

let rec fold ~init ~f l = 
    match l with 
    | []  -> init 
    | h :: t -> fold ~init:(f init h) ~f:f t 

我希望現在能夠實現length像這

let length = fold ~init:0 ~f:(fun c _ -> (c + 1)) 

...但編譯呃與

Values do not match: 
    val length : '_a list -> int 
    is not included in 
    val length : 'a list -> int 

當然抱怨,我知道我可以實現length這樣

let length l = fold ~init:0 ~f:(fun c _ -> (c + 1)) l 

...但我不明白爲什麼我不能從兩邊去掉後l=

我哪裏錯了?

回答

1

這是價值限制。你的長度定義在技術意義上不是一個價值。 Stack Overflow已經在這裏討論了這個問題。我會尋找一個好的。

這是一個相當不錯的:

Why does a partial application have value restriction?

+0

深的東西...謝謝! – kjo 2014-11-09 00:34:58

+1

這不是* *深*:膠囊摘要是,除非你確定它是安全的,否則你不能使事物變成多態。在可變數據的語言(如OCaml)中,它並不總是安全的。 「價值限制」是何時安全的近似值。這不是一個特別接近的近似值,但它很容易記住。 – 2014-11-09 04:37:34

+0

我猜想,我有一個「短腦袋」,因爲對於我來說,「價值限制」是一個解決方案(更不用說是一個很好的解決方案),對於在支持多態的語言中實現類型推斷的問題類型和可變數據。順便說一下,我希望OCaml的設計師們不會因爲易於記憶而定居下來,而是爲了獲得最大的表現力,畢竟,使用電腦的重點在於超越我們能做的事情。 – kjo 2014-11-09 14:05:10