问题
How can I write a no-op statement in F#?
Specifically, how can I improve the second clause of the following match statement:
match list with
| [] -> printfn "Empty!"
| _ -> ignore 0
回答1:
Use unit for empty side effect:
match list with
| [] -> printfn "Empty!"
| _ -> ()
回答2:
The answer from Stringer is, of course, correct. I thought it may be useful to clarify how this works, because "()" insn't really an empty statement or empty side effect...
In F#, every valid piece of code is an expression. Constructs like let
and match
consist of some keywords, patterns and several sub-expressions. The F# grammar for let
and match
looks like this:
<expr> ::= let <pattern> = <expr>
<expr>
::= match <expr> with
| <pat> -> <expr>
This means that the body of let
or the body of clause of match
must be some expression. It can be some function call such as ignore 0
or it can be some value - in your case it must be some expression of type unit
, because printfn ".."
is also of type unit
.
The unit
type is a type that has only one value, which is written as ()
(and it also means empty tuple with no elements). This is, indeed, somewhat similar to void
in C# with the exception that void
doesn't have any values.
BTW: The following code may look like a sequence of statements, but it is also an expression:
printf "Hello "
printf "world"
The F# compiler implicitly adds ;
between the two lines and ;
is a sequencing operator, which has the following structure: <expr>; <expr>
. It requires that the first expression returns unit
and returns the result of the second expression.
This is a bit surprising when you're coming from C# background, but it makes the langauge surprisingly elegant and consise. It doesn't limit you in any way - you can for example write:
if (a < 10 && (printfn "demo"; true)) then // ...
(This example isn't really useful - just a demonstration of the flexibility)
来源:https://stackoverflow.com/questions/2704267/f-how-to-write-an-empty-statement