Почему эта функция истины / ложности не работает в SML?
val implies =
fn x y = case x of false andalso case y of false => true
| fn x y = case x of false andalso case y of true => true
| fn x y = case x of true andalso case y of false => false
| fn x y = case x of true andalso case y of true => true;
Я не могу заставить это скомпилировать. Я относительно новичок в SML, поэтому не совсем понимаю общий язык и синтаксис. Что я сделал не так?
2 ответа
Есть разные вещи не так:
- Нет аргументов в
implies
сделать сопоставление с образцом напрямую. case x of
для сопоставления с конкретными значениями, а не какif/else
выражение, которое принимает логические выражения.- Синтаксис лямбды должен начинаться с
fn x => ...
,
Быстрое исправление:
fun implies x y =
case (x, y) of
(false, false) => true
| (false, true) => true
| (true, false) => false
| (true, true) => true
который может быть переписан для удобства чтения как:
fun implies false false = true
| implies false true = true
| implies true false = false
| implies true true = true
или более кратким, используя правило логики высказываний:
fun implies x y = (not x) orelse y
Что касается анонимных функций,
fun implies x y = (not x) orelse y
можно записать как
val implies = fn x => fn y => (not x) orelse y
однако, как вы видите, на самом деле не имеет смысла делать это таким образом (в данном конкретном случае).
Анонимные функции в SML принимают только один аргумент. Карринг аргументов работает, потому что fun
Ключевым словом является синтаксический сахар (также называемый производной формой)
val rec implies = fn x => fn y =>
case (x, y) of
(x,y) => (not x) orelse y
Кейс используется потому, что в исходной функции у нас могло быть какое-то сопоставление с образцом, которое затем транслировалось прямо в кейс, и rec
потому что исходная функция могла быть рекурсивной.
Таким образом, второй пример, который дал @pad, эквивалентен:
val rec implies = fn x => fn y =>
case (x, y) of
(false, false) => true
| (false, true) => true
| (true, false) => false
| (true, true) => true