Несколько указателей:
- Вы почти никогда не используете циклы в ML.В любое время, когда вам нужно выполнить итерацию, напишите рекурсивную функцию.
- Вам редко нужно указывать типы.В этом случае ML может вывести из того факта, что вы звоните
tl(x)
, что x
должен быть списком. - Вместо использования
hd(x)
и tl(x)
для декомпозиции списка выобычно делают это с сопоставлением с шаблоном в аргументах функции.Вместо одного аргумента x
напишите аргумент как x::xs
;x
будет присвоен заголовку списка, а xs
- хвосту. - Вместо использования условных операторов для проверки структуры вашего аргумента (в данном случае, является ли ваш список пустым илинет), вы можете написать несколько определений функций с различными шаблонами.ML будет пробовать их один за другим, пока не найдет подходящий.
- Тело вашей функции должно быть выражением , которое возвращает ваше возвращаемое значение. Все в ML - это выражение;даже
if x then a else b
- это, по сути, функция, которая возвращает либо a
, либо b
.
Имея все это в виду, вот что поможет вам начать:
fun select([], funct) = []
| select(x::xs, funct) = ...
Два случая здесь заменяют ваше while
условие - первое будет оценено только тогда, когда ваш список nil
.Шаблон во втором случае автоматически присваивает значения заголовку и хвосту вашего списка.Это определение предназначено, чтобы быть рекурсивным;select([],funct)=[]
- ваш базовый случай, а select(x::xs,funct)=...
должен включать вызов select(xs,funct)
.