开发者

Why is in F# a dummy symbol literal needed between pipe and when?

开发者 https://www.devze.com 2023-01-14 03:01 出处:网络
I am new to F# and fiddling just around with it. What get\'s me is: let rec fact n = match n with dummy when n < 2 -> 1

I am new to F# and fiddling just around with it. What get's me is:

let rec fact n =
  match n with 
    | dummy when n < 2 -> 1
    | _ -> n * fact (n - 1)
开发者_JAVA技巧
let x = 6
printfn "%d! = %d" x (fact x)

Why does F# needs this dummy placeholder between pipe and when? Dummy is even the whole time undefined and the compiler seems in some way to need and ignore it at the same time like a needed ghost symbol.

Thanks in advance.


The symbol doesn't have to be a dummy and can appear in the when clause. For example, your function could be rewritten:

let rec fact = function
| n when n < 2 -> 1 
| n -> n * fact (n - 1) 

Here, because we're using an anonymous pattern match with function rather than match ... with, the identifier actually matters.

Frequently you'll use a more complicated pattern, like

match p with
| i,j when i < j -> true
| _ -> false

Because the pattern being matched against almost always matters even when there is a when clause, there isn't a special form which allows a when clause without any pattern.

Of course, if you really do want it to be a dummy, you can use the pattern _ so that you don't need to come up with a new identifier name:

let rec fact n = 
  match n with  
  | _ when n < 2 -> 1 
  | _ -> n * fact (n - 1) 


As others already explained, the dummy value in your example can be replaced by an ignore pattern (written as _) to keep the code more succinct. The match construct is the most powerful when you need to decompose some value and in that case, you need the ability to define new symbols inside the pattern matching.

However, in your example, you're not really decomposing the value, so I would prefer simple if ... then expression instead of more complex match:

let rec fact n = 
  if n < 2 then 1 
  else n * fact (n - 1) 

I think this is a more readable way of writing your original function (and is as functional as the other version - match is simply more suitable when working with more complex types than integers).


dummy just means a value (or more accurately pattern) that can match the value between match and with. It is not visible outside your function, only local to the first case.

As kvb said you're not forced to name it dummy, it can be any valid F# identifier.

It's very powerful since it can be used for decomposing types like tuples or list:

match l with
| head::tail -> tail // returns tail
| _ -> [] // returns an empty list
0

精彩评论

暂无评论...
验证码 换一张
取 消