Как использовать сопоставление на уровне аргумента, это возможно? 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

Другие вопросы по тегам