#sml #smlnj
#sml #smlnj
Вопрос:
Я должен написать это в sml / nj Я попробовал, и это то, что я сделал:
Я хочу, чтобы функция all возвращала положительное число при запуске функции, но, например, когда я даю [1,2,3] [1,1,2,3,1,2,3,1]
, она возвращает неистощительный сбой сопоставления. Что не так с функцией и что я могу сделать, чтобы увидеть, существуют ли элементы первого списка во втором?
fun elem num [] = false
| elem num (x::xs) = if num = x then true else elem num xs
fun all [] [] =
let
fun qwe [] [] acc = acc
| qwe (x::xs) (z::zs) acc = if elem x (z::zs) then qwe xs (z::zs) (1 acc) else qwe xs (z::zs) acc
in
qwe [] [] 0
end
Ответ №1:
В вашем определении all
вы, похоже, склоняетесь к мысли о []
том, что это общий список, а не пустой список.
Единственный шаблон, который на самом деле появляется в вашем определении all
— это [] []
(два пустых списка). Это, безусловно, случай неисчерпывающего сопоставления.
Поскольку вспомогательная функция qwe
выполняет фактическую работу, на самом деле нет никакого смысла в том, чтобы сопоставлять шаблоны с all
собой. Общая форма all
может быть:
fun all xs ys =
let
fun qwe = (*insert definition*)
in
qwe xs ys 0
end;
(использование здесь zs
вместо ys
выглядит немного неудобно)
Определение que
должно содержать 2-4 шаблона. Определение из 4 шаблонов (требуется для некоторых функций, которые работают с двумя списками):
fun qwe [] [] acc = (*insert def*)
| qwe [] (y::ys) acc = (*insert def*)
| qwe (x::xs) [] acc = (*insert def*)
| qwe (x::xs) (y::ys) acc = (*insert def*)
Это последнее дает 4 случая, по одному для каждой логической комбинации первого списка, а второй список пуст. Иногда вам не нужно писать отдельный код для каждого из них. Например,
fun qwe [] [] acc = (*insert def*)
| qwe [] ys acc = (*insert def*)
| qwe (x::xs) ys acc = (*insert def*)
объединяет 3-й и 4-й регистры в один регистр.
Если вы посмотрите на свое фактическое определение elem
, вы поймете, что оно прекрасно обрабатывает случай empty ys
, поэтому в вашем определении qwe
вы действительно можете просто иметь два шаблона, основанных на том, что xs
делает:
fun qwe [] ys acc = (*insert def*)
| qwe (x::xs) ys acc = (*insert def*)
Поскольку ys
может соответствовать как пустым, так и непустым спискам, приведенный выше шаблон является исчерпывающим.
С соответствующими определениями (которые у вас, по сути, уже есть) для двух вышеупомянутых случаев que
, ваша функция all
будет работать:
- all [1,2,3] [1,1,2,3,1,2,3,1];
val it = 3 : int