2016-09-09 73 views
3

功能規格:簡單ocaml的錯誤類型

寫一個函數any_zeroes : int list -> bool返回true,當且僅當輸入列表中包含至少一個0

代碼:

let any_zeroes l: int list = 
    List.exists 0 l 

錯誤:

This expression has type int but an expression was expected of type 
     'a -> bool 

我不知道爲什麼Ocaml在0上出現問題時,我將l標記爲int list。如果有人可以幫我解決這個問題,將不勝感激!

謝謝!

+2

改爲使用'List.mem'。 –

回答

3

所以,首先,你沒有標註lint list,語法:

let any_zeroes l: int list 

意思就是any_zeroes是一個函數,返回一個int list。註釋它以正確的方式,如下:

let any_zeroes (l : int list) : bool 

其次,事實上,你馬克東西不會改變程序的語義。它是一個類型約束,它告訴類型推斷系統,你希望這個類型統一到你指定的任何地方。如果一個類型檢查器不能這樣做,它將會出錯並出錯。類型檢查器不需要你的約束,它們大多是爲了可讀性而添加的。 (我認爲他們也是你需要的課程所要求的)。

最後,錯誤指出您不是l(即您認爲已註釋的),而是指0。並且該消息告訴您,List.exists函數正在接受類型爲'a -> bool的函數作爲第一個參數,但您試圖用0提供類型爲int的函數。所以,類型系統試圖統一int'a list,並且沒有這樣的'aint = 'a list,所以它不檢查類型。所以你需要通過一個函數,或者按照Anton的建議使用List.mem

1

類型註釋let any_zeroes l: int list = ...表示any_zeroes l的類型是int list;這不是你在這裏的意思。

關係到你的規範正確的類型標註爲:

let any_zeroes 
: int list -> bool 
= fun l -> List.exists 0 l 

在頂層,它反饋:

= fun l -> List.exists 0 l;; 
        ^
This expression has type int but an expression was expected of type 
    'a -> bool 

事實上,這個表達式失敗的原因爲List.exists類型來進行類型檢查:

# List.exists;; 
- : ('a -> bool) -> 'a list -> bool = <fun> 

第一個參數是一個謂詞,它0不是。 一個正確的實現是:

let any_zeroes 
: int list -> bool 
= let is_zero x = x = 0 in 
    fun l -> List.exists is_zero l