簡體   English   中英

輸入與printfn不匹配

[英]Type mismatch with printfn

我有一個函數連接兩個字符串,並在它們之間放置一個逗號和空格並返回它。 我不能打印結果。

let concat first second =
    first + ", " + second


printfn "%s" concat "hello" "world"

類型不匹配。 期待'字符串 - >'a - >'b - >'c'但給出'字符串 - >單位'類型'' - >'b - >'c'與類型'單位'不匹配(使用外部F#編譯器)

這個表達式應該有'string'類型,但這里有'string - > string - > string'類型

如何正確打印返回的字符串?

編輯:似乎我需要圍繞調用concat的括號。 為什么需要這個?

let concat first second =
    first + ", " + second


printfn "%s" (concat "hello" "world")

Robert Nielsen的回答是正確的,但讓我嘗試一種不同的方式來解釋它,因為如果你是F#的新手,可能很難理解如下的表達式:

(((printfn "%s") concat) "hello") "world"

所以想一想:在F#中,函數可以作為輸入傳遞給其他函數。 例如,您可以將concat函數作為輸入傳遞給List.reduce

List.reduce concat ["one"; "two"; "three"]
// Returns "one, two, three"

現在,您可以通過兩種方式閱讀此內容。 函數調用可以保留優先級或右優先級。 即,如果函數調用具有正確的優先級,那么["one"; "two"; "three"] ["one"; "two"; "three"] ["one"; "two"; "three"]列表將被認為是concat函數的第一個參數(因為它是最右邊的,因此具有優先權)。 或者如果函數調用具有優先權,那么該列表將是List.reduce函數的第二個參數,而concat函數將是第一個參數。 F#使后者(左優先)成為默認值:在沒有括號的情況下,函數名稱后面的所有內容都被認為是該函數的參數。 所以以下內容:

printfn "%s" concat "hello" "world"

讀作:“使用四個參數調用printfn函數:字符串,函數和另外兩個字符串”。 如果希望字符串“hello”和“world”成為concat參數,則必須添加括號,以便F#將解析具有更高優先級的concat調用(如您已經發現的那樣):

printfn "%s" (concat "hello" "world")

這被解讀為:“使用兩個字符串作為參數調用concat函數,然后獲取該函數調用的結果並將其作為第二個參數傳遞給printfn ”。

但想想這個:如果默認是另一種方式,並且函數調用具有正確的優先級 - 你如何將括號放入List.reduce示例中以使其按您想要的方式工作? 你想要的是“使用兩個參數調用List.reduce :第一個是函數,第二個是字符串列表。” 但是你如何為此添加括號:

List.reduce concat ["one"; "two"; "three"]

得到那個結果? 嗯,這會工作:

(List.reduce concat) ["one"; "two"; "three"]

但在我看來,這將令人困惑。 要理解這個表達式,你必須要了解F#currying是如何工作的,這是一個通常需要一段時間才能解決問題的概念。 而對於左優先級函數調用,表達式someFunction abc總是表示“使用三個參數調用someFunction ”,無論這三個參數中的任何一個是函數。

我希望這個冗長的解釋能幫助你更好地理解F#函數調用。

由於F-sharp運算符優先級: 符號和運算符參考

編輯:您可以將其視為轉向

(((printfn "%s") concat) "hello") "world"

(printfn "%s") ((concat "hello") "world")

但撒上一些類型的推論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM