2016-02-14 111 views
-1

什麼導致REPL打印函數簽名而不是函數結果?是什麼導致REPL打印函數簽名而不是函數結果?

我試圖執行以下行:

let email = Email "abc.com";; 
email |> sendMessage |> ignore;; 

的代碼如下

type PhoneNumber = 
    { CountryCode:int 
     Number:string } 

type ContactMethod = 
    | Email of string 
    | PhoneNumber of PhoneNumber 

let sendMessage contact = function 
    | Email _ -> printf "Sending message via email" 
    | PhoneNumber phone -> printf "Sending message via phone" 

// c. Create two values, one for the email address case and 
// one for the phone number case, and pass them to sendMessage. 
let email = Email "abc.com";; 
email |> sendMessage |> ignore;; 

我得到以下結果:

type PhoneNumber = 
    {CountryCode: int; 
    Number: string;} 
type ContactMethod = 
    | Email of string 
    | PhoneNumber of PhoneNumber 
val sendMessage : contact:'a -> _arg1:ContactMethod -> unit 
val email : ContactMethod = Email "abc.com" 

> 
val it : unit =() 

我希望這樣的事情:

「通過電子郵件發送消息」

回答

6

sendMessage功能需要參數:無限制型'a的一個名爲contact和匿名(_arg1在簽名)ContactMethod

當您提供emailsendMessage時,您會收到一個函數,該函數需要ContactMethod並返回unit。然後您可以ignore這個功能。

要麼刪除contact參數(更地道):

let sendMessage = function 
    | Email _ -> printf "Sending message via email" 
    | PhoneNumber phone -> printf "Sending message via phone" 

或匹配就可以了(可能更容易理解):現在

let sendMessage contact = 
    match contact with 
    | Email _ -> printf "Sending message via email" 
    | PhoneNumber phone -> printf "Sending message via phone" 

sendMessageContactMethod -> unit類型的和你不不再需要ignore了。

+2

經驗法則。如果你必須使用'ignore'並且不知道爲什麼,那麼仔細看一下函數簽名,可能性是你潛伏在代碼中的潛在錯誤。我發現調用.NET代碼的'ignore'比F#函數的用法更多,特別是當.NET代碼有副作用時'StringBuilder追加',你需要副作用但不是調用的結果。 –

+1

另外,如果你曾經使用'按任意鍵繼續',那麼你會使用'Console.ReadKey()|> ignore';再次你需要副作用,但不是結果。 –

相關問題