2015-08-26 22 views
0

此代碼F#類型不匹配而調用函數

let rec readNLines n list = 
if n = 0 then 
    list 
else 
    readNLines(n-1,readInt()::list) 

Type mismatch. Expecting a 'a but given a 'a -> 'a  
The resulting type would be infinite when unifying ''a' and 
''a -> 'a' (using built-in F# compiler) 

結束,但是當最後一行改爲

readNLines(n-1,(readInt()::list)) 

readNLines(n-1)(readInt()::list) 
運行正常

問題是:爲什麼? :|只有

回答

8

的最後一個版本可以正常工作,因爲readNLines有兩個參數,但

readNLines (n - 1, readInt() :: list) 

通過只有一個參數(這是由一個intlist的元組)。

readNLines (n - 1) (readInt() :: list) 

將它們作爲兩個單獨的參數傳遞 - 這裏的區別是使用逗號(元組)和空格(兩個參數)。

順便說一句,當你使用更多的空格時(和我一樣),這會變得更清晰,因爲單個元素更容易識別。

2

看看這兩個功能:

> let f1 a b = a + b 

val f1 : a:int -> b:int -> int 

> let f2 (a, b) = a + b 

val f2 : a:int * b:int -> int 

正如你所看到的,他們有略微不同的類型。在功能f1你部分應用參數(你會看到在這裏使用的術語「咖喱功能」),在功能f2你傳遞一個參數的元組在一個「去」,或者你可以認爲它只有一個單個參數(一個「不安全」功能)。

你正在做的是定義一個函數f1樣式,但稍後調用它的樣式,這會混淆編譯器。