1
我寫了我認爲非常直接的F#代碼,但編譯器似乎正在跳出類型推斷。而不是從受歧視的工會中推斷出來,而是通過一個通用的推論。但我不明白爲什麼,因爲我的代碼不允許通用推理。爲什麼F#「Generic-izing」我的歧視聯盟
下面的代碼:
module Log
open System
type LogInput =
| Message of (int * string)
| Error of Exception
| Process of (string * unit -> int)
let log i =
match i with
| Message(indent, str) ->
str
|> printfn "Message() %s%s" (String.replicate (indent * 4) " ")
| Error(err) ->
err.ToString()
|> printfn "Error() %s"
| Process(name, f) ->
printfn "Beginning %s..." name
printfn "Completed %s\nReturn Code: %i" name <| f()
編譯器正確推斷爲indent
,str
和err
類型,但要推斷'a
和'b
爲name
和f
(不使得或者基於感歧視的聯盟或使用)。這是怎麼回事?
錯誤消息:
Log.fs(18,16): error FS0001: This expression was expected to have type
string * unit -> int
but here has type
'a * 'b
運算符優先級的定義是這樣的方式,因爲它是編寫一個帶元組的函數(比如,.NET方法是這樣定義的)比一個元素是函數的元組(這裏是你想要的)更常見。 – Tarmil
@Tarmil - 同意,這是更常見的用例,它是有道理的。但是,對於這個語言來說,這是一個相當新的東西,一旦我把它放在我的腦海裏,'string * unit - > int'意味着'string *(unit - > int)',我無法弄清楚發生了什麼。如果編譯器輸出更加明確(比如'(string * unit) - > int'),我會立即識別錯誤。 – JDB