Как использовать сопоставление на уровне аргумента, это возможно? Guards?
Например
let When true d = d
let foo = () |> When false
Так что у меня есть побочный эффект, который мне не нравится, потому что это ошибка: MatchFailureException
Я знаю, что у меня может быть хороший побочный эффект здесь: let foo = if false then ()
Но предупреждение Incomplete pattern matches on this expression.
говорит мне, как я могу добавить то, что мне нужно. Я просто не знаю, как или если это возможно? Иначе, почему я даже могу использовать значения в качестве аргументов?
кстати: я знаю, что я могу написать When b d = if b then d else ()
но вопрос более общий.
добавил объяснение в хаскелл
let wh :: Bool -> IO () -> IO ()
wh True f = f
wh False f = return ()
2 ответа
Тот факт, что это разрешено, является скорее причудой спецификации, и действительно, так что вы можете делать такие вещи, как
let (a,b) = 1,2
Ваш вопрос не очень понятен, но я думаю, что вы ищете что-то вроде
let 1 |2 = 1
По сути, синтаксис такой же, как после матча, за исключением того, что вам не нужен первый |
Заметьте, это учитывает самый сумасшедший кусок кода F#, который я написал некоторое время:
let 1 = 2
Это скомпилирует (с предупреждением), но потерпит неудачу во время выполнения.
Когда вы пишете что-то вроде:
let When true d = d
Вы говорите F# создать функцию, которая принимает два аргумента, и вы сравниваете два аргумента с шаблонами true
а также d
соответственно. true
шаблон является неполным и завершается неудачей, когда вход не true
значение. d
шаблон является переменной привязкой, и это всегда успешно.
Тот факт, что вы можете использовать неполные шаблоны в аргументах объявлений функций, не особенно полезен (но я полагаю, вы могли бы использовать более сложный шаблон, который компилятор просто не может проверить).
Неполные шаблоны действительно имеют смысл, только когда вы используете match
или когда вы используете function
, function
Ключевое слово дает вам что-то вроде охранников в других языках - но оно работает только с функциями, принимающими один аргумент. Если вы измените When
чтобы принять кортеж, вы можете написать:
let When = function
| true, f -> f()
| false, _ -> ()
Кроме того, вы можете изменить порядок аргументов (и использовать карри), как в ответе от Vesa.AJK