F # совпадает с двумя значениями - PullRequest
3 голосов
/ 26 января 2009

Я довольно новичок в F #, и я хотел сравнить два значения с синтаксисом (соответствует ... с ...)

Проблема возникает, когда я пытаюсь сравнить два значения следующим образом:

let value1 = 19
let isValue1 y =
    match y with
    | value1 -> y + 1
    | _ -> y

Я получаю предупреждение о том, что часть кода «| _ -> y» никогда не будет достигнута. Почему это?

Я знаю, что могу сделать следующее, чтобы заставить функцию работать так, как я хочу:

let value1 = 19
let isValue1 y =
    match y with
    | _ when y = value1 -> true
    | _ -> false

Это также работает

let value1 = 19
let isValue1 y =
    match y with
    | 19 -> true
    | _ -> false

Мне просто любопытно, почему я не могу этого сделать и как на самом деле работает матч.

Ответы [ 3 ]

9 голосов
/ 26 января 2009

Значение1 в операторе сопоставления определяется как новая переменная, значение которой равно y (как совпадение). Значение1, которое вы определяете чуть выше, игнорируется, как если бы вы объявили локальную переменную в функции C # с тем же именем, что и у переменной класса. По этой причине первое условие соответствия будет соответствовать всему , а не только ранее определенному значению value1, отсюда и ошибка. Надеюсь, что проясняет дело.

5 голосов
/ 26 января 2009

Сопоставление с образцом является одновременно управляющей конструкцией (какой код выполняется далее) и связывающей конструкцией (например, «let», связывает имя со значением). Итак, когда вы делаете

match expr with
| name -> ...

шаблон («имя») всегда совпадает, а идентификатор «имя» просто привязывается к значению выражения. Вот почему сопоставление с образцом в основном используется с различимыми объединениями (типами дел), где вы сопоставляете на основе структуры. Э.Г.

match someOption with
| Some(x) -> ... // binds x
| None -> ...

match someList with
| h :: t -> ... // binds h and t to head/tail
| [] -> ...
1 голос
/ 01 февраля 2009

Вы можете просто сопоставить входные данные с литералами / идентификаторами, отмеченными атрибутом [<Literal>], не связывая его.

Например:

#light
[<Literal>]
let E  = 2.718281828459


let isE x =
    match x with
    | E -> true
    | _ -> false

print_any (isE 3.2)
print_any (isE E)

Согласно Крис Смит

...