【问题标题】:Confusing F# compiler message令人困惑的 F# 编译器消息
【发布时间】:2014-12-22 20:06:10
【问题描述】:

以下 sn-p 说明了我遇到的错误。即使两个匹配分支都返回相同的东西;我得到错误,“这个表达式应该有单位类型,但这里有类型'a - >单位”我不知道编译器在这里想要什么......

open System.IO 

let FileContent contents =  
  match contents with  
  | "" -> None  
  | c -> Some(c)  

let WriteSomething (contents:string) =  
  let writer = new StreamWriter("")  
  writer.Write( contents ) |> ignore  

let DoStuffWithFileContents =  
  let reader = new StreamReader( "" )  
  let stuff = reader.ReadToEnd()  
  match stuff |> FileContent with  
  | Some(c) -> WriteSomething c  
               |> ignore  
  | None -> ignore  // <- error on "ignore"

【问题讨论】:

    标签: f# unit-type


    【解决方案1】:

    ignore 运算符实际上是一个函数,它接受单个输入并返回 unit type(F# 中相当于 void)。因此,当您拥有 -&gt; ignore 时,您将返回 ignore 函数。

    改为使用() 来表示unit 类型的值:

      | Some(c) -> WriteSomething c  
                   |> ignore  
      | None -> ()
    

    但实际上,由于StreamWriter.Write 返回void,所有这些ignore 都是不必要的。你可以很容易地写成这样:

    let WriteSomething (contents:string) =  
      let writer = new StreamWriter("")  
      writer.Write(contents)   
    
    let DoStuffWithFileContents =  
      let reader = new StreamReader("")  
      let stuff = reader.ReadToEnd()  
      match stuff |> FileContent with  
      | Some(c) -> WriteSomething c  
      | None -> () 
    

    或者更好,使用Option.iter

    let WriteSomething (contents:string) =  
      let writer = new StreamWriter("")  
      writer.Write(contents)
    
    let DoStuffWithFileContents =  
      let reader = new StreamReader("")  
      let stuff = reader.ReadToEnd()  
      stuff |> FileContent |> Option.iter(WriteSomething)
    

    【讨论】:

      【解决方案2】:

      通过在最后一行返回ignore,您返回的是一个函数,而不是一个简单的值。

      ignore 的重点是将事物转换为()。您的最后一行可以直接返回()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-30
        • 2014-10-11
        • 2019-06-04
        • 2018-11-02
        • 2015-11-24
        • 2022-11-22
        相关资源
        最近更新 更多