简体   繁体   中英

Confusing F# compiler message

The following snippet illustrates the error I'm getting. Even though both match branches return the same thing; I get error, "This expression was expected to have type unit but here has type 'a -> unit" I have no clue what the compiler wants here...

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"

The ignore operator is actually a function that takes a single input and returns the unit type (F#'s equivalent of void ). So when you have -> ignore you're returning the ignore function.

Instead, use () to represent the value of the unit type:

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

But actually, since StreamWriter.Write returns void , all these ignore 's are unnecessary. You could just as easily write this as:

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 -> () 

Or even better, use 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)

By returning ignore on your last line you are returning a function, not a simple value.

The point of ignore is to convert things to () . Your last line can simply return () directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM