什么原因导致REPL打印函数签名而不是函数结果?

Sco*_*rod -1 f#

什么原因导致REPL打印函数签名而不是函数结果?

我试图执行以下行:

let email = Email "abc.com";;
email |> sendMessage |> ignore;;
Run Code Online (Sandbox Code Playgroud)

代码如下

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;;
Run Code Online (Sandbox Code Playgroud)

我得到以下结果:

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 = ()
Run Code Online (Sandbox Code Playgroud)

我期待这样的事情:

"通过电子邮件发送消息"

Car*_*Dev 6

您的sendMessage函数有两个参数:一个名为contactunrestricted type 'a,一个是匿名(_arg1在签名中)ContactMethod.

当你提供emailsendMessage你一个功能,需要一个ContactMethod并返回unit.然后你ignore这个功能.

删除contact参数(更惯用):

let sendMessage = function
    | Email _ -> printf "Sending message via email"
    | PhoneNumber phone -> printf "Sending message via phone"
Run Code Online (Sandbox Code Playgroud)

或匹配(可能更容易理解):

let sendMessage contact =
    match contact with
    | Email _ -> printf "Sending message via email"
    | PhoneNumber phone -> printf "Sending message via phone"
Run Code Online (Sandbox Code Playgroud)

现在,sendMessage是类型ContactMethod -> unit,你不再需要ignore了.

  • 经验法则.如果你不得不使用`ignore`并且不知道为什么,那么请认真看看函数签名,可能是你潜在的错误隐藏在代码中.我发现调用.NET代码比使用F#函数更多地使用`ignore`,特别是当.NET代码有副作用时,例如``StringBuilder append`,你需要副作用而不是调用的结果. (2认同)