Почему в F # фиктивный символ необходим между pipe и когда? - PullRequest
3 голосов
/ 29 августа 2010

Я новичок в F # и возлюсь с ним.Что я понял:

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

let x = 6
printfn "%d! = %d" x (fact x)

Зачем F # этот фиктивный заполнитель между каналом и когда?Dummy даже целое время не определено, и компилятор, кажется, каким-то образом нуждается и игнорирует его одновременно как необходимый символ-призрак.

Ответы [ 3 ]

10 голосов
/ 29 августа 2010

Символ не должен быть фиктивным и может появляться в предложении when.Например, ваша функция может быть переписана:

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

Здесь, поскольку мы используем анонимное сопоставление с function вместо match ... with, идентификатор действительно имеет значение.

Часто вы будете использовать более сложный шаблон, такой как

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

Поскольку сопоставляемый шаблон почти всегда имеет значение, даже когда есть предложение when, нет специальной формы, которая позволяет when предложение без какого-либо шаблона.

Конечно, если вы действительно хотите, чтобы он был фиктивным, вы можете использовать шаблон _, чтобы вам не приходилось придумывать новое имя идентификатора.:

let rec fact n = 
  match n with  
  | _ when n < 2 -> 1 
  | _ -> n * fact (n - 1) 
9 голосов
/ 29 августа 2010

Как уже объяснили другие, значение dummy в вашем примере можно заменить шаблоном игнорирования (записанным как _), чтобы сделать код более лаконичным.Конструкция match является наиболее мощной, когда вам нужно разложить какое-то значение, и в этом случае вам нужна возможность определять новые символы внутри сопоставления с образцом.

Однако в вашем примере вы недействительно разлагает значение, поэтому я бы предпочел простое выражение if ... then вместо более сложного match:

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

Я думаю, что это более читабельный способ написания вашей исходной функции (и такой же функциональный, какдругая версия - match просто больше подходит для работы с более сложными типами, чем целые числа).

1 голос
/ 29 августа 2010

dummy просто означает значение (или, точнее, шаблон), которое может соответствовать значению между match и with.Он не виден за пределами вашей функции, только локально для первого случая.

Как сказал kvb, вы не обязаны называть его dummy, это может быть любой допустимый идентификатор F #.

Это очень мощный инструмент, поскольку его можно использовать для разложения типов, таких как кортежи или списки:

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