Стандартный ML: проверка условий при итерации списка - PullRequest
0 голосов
/ 12 марта 2019

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

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

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

f.ex

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

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; внутри или снаружи, если условия для такого рода работы.

1 Ответ

0 голосов
/ 12 марта 2019

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

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.

...