[英]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.