как я могу перебрать список с условием проверки
fun check i nil = []
| check i (x::xs) = if i=x
then //dowork
else //iterate;
Я хочу перебрать список и проверить, соответствует ли входная переменная существующему элементу в списке.
Я бы назвал это комбинатором предикатов. Он уже существует в стандартной библиотеке и называется List.exists
. Но вы также можете сделать это самостоятельно:
fun exists p [] = false
| exists p (x::xs) = p x orelse exists p xs
Это упрощение попытки if-then-else, которое выглядит следующим образом:
fun exists p [] = false
| exists p (x::xs) = if p x then true else exists p xs
If-then-else действительно не требуется, когда тип результата является логическим, поскольку orelse
, andalso
и not
являются короткозамкнутыми (не будут оценивать свой второй операнд, если можно определить результат с первым).
Используя эту функцию List.exists
, чтобы проверить, содержит ли список определенный элемент, вы должны создать p
, который сравнивает элемент списка с некоторым заданным значением, например ::
fun check y xs = List.exists (fn x => ...) xs
Это может показаться немного сложнее, чем просто написать check
рекурсивно с нуля,
fun check y [] = false
| check y (x::xs) = ... orelse check y xs
но решение с использованием функций более высокого порядка является предпочтительным по нескольким причинам.
Во-первых, опытный читатель быстро обнаружит, что вы делаете, увидев List.exists
: Ах, вы сканируете список для элемента с предикатом. Принимая во внимание, что если ваша функция явно рекурсивна, читатель должен будет прочитать всю схему рекурсии: ОК, функция не делает ничего прикольного, что я знал бы, например, если бы видел. List.exists
.