Стандартный ML: проверка условий при повторении списка

#functional-programming #sml

#функциональное программирование #sml

Вопрос:

я изучаю язык программирования Standard ML, и мне интересно, как я могу выполнить повторение списка с условием проверки.

В других языках у нас есть циклы for, подобные :

 var input;
for(var i = 0; i < arr.length; i  ) {
   if(arr[i] == input) {
      //you have arrived at your condition...
   } else {
     //other case
   }
}
  

например

я хочу выполнить итерацию по списку и проверить, соответствует ли входная переменная существующему элементу в списке.

 i = 5  
xs = [1,5,2,3,6] --> the element matches after one iteration.

fun check i nil = []
| check i (x::xs) = if i=x 
                    then //dowork 
                    else //iterate;
  

Я просмотрел множество документов о том, как это реализовать, но безуспешно.

Было бы действительно полезно, если бы кто-нибудь мог дать мне некоторые объяснения относительно того, как я могу использовать let val A in B end; внутри или вне условий if для такого рода работы.

Ответ №1:

как я могу выполнить повторение списка с условием проверки

 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 .