Как сократить список в стандартных мл

Я только начинаю работать со стандартным мл, и мне действительно трудно понять список на этом языке. Итак, мой вопрос: как сократить список в мл? Например, если у меня есть список [1,2,3,4,5,6], я хочу сократить его до [1,2]. Что у меня есть до сих пор:

fun shorten(i, l) = let val newlen = i in newlen = length l//in correct

то, что я хочу, - это функция, которая будет принимать i как место, где пользователь хочет сократить список, а l - это список. В этом случае ввод должен выглядеть как shorten(2, [1,2,3,4,5,6], а вывод должен выглядеть как [1,2].


person user4075830    schedule 27.10.2014    source источник
comment
Какие у вас есть идеи вместо написания случайного кода, которые могли бы способствовать написанию правильного решения?   -  person pyon    schedule 27.10.2014
comment
То, что я пишу выше, - это то, что я получил до сих пор, и я пытаюсь создать переменную newlen, равную i, и установить ее равной новой длине списка. Я новичок с мл, поэтому я немного потерял здесь.   -  person user4075830    schedule 27.10.2014


Ответы (2)


Эта функция должна сделать это:

fun shorten(_, nil) = nil
  | shorten(0, _) = nil
  | shorten(i, x::xs) = x::shorten(i - 1, xs)

Как вы заметили, эта функция не генерирует никаких исключений, когда i больше, чем длина списка. Подход, использующий исключения, будет следующим:

exception IllegalArgument

fun shorten(_, nil) = nil
  | shorten(0, _) = nil
  | shorten(i, x::xs) =
    if i > length(x::xs) then raise IllegalArgument
    else x::shorten(i - 1, xs)

В SML вам нужно объявить любой тип исключения с помощью exception, прежде чем он будет вызван с помощью raise. В противном случае тип исключения не привязан к среде, и интерпретатор будет жаловаться на то, что символ неизвестен.

person Community    schedule 27.10.2014
comment
Спасибо. Могу я спросить, как проверить на ошибку в этом случае? что у меня есть: fun shorten(_, nil) = raise Error | shorten(0, _) = raise Error | shorten(i, x::xs) = if i > length (x::xs) then raise Error else x::revert((i - 1), xs)<code>&lt;html&gt;</code> похоже не работает - person user4075830; 28.10.2014

Базовая библиотека SML содержит функцию List.take для выполнения требуемой задачи в рамках Структура списка.

- fun shorten ( toHowMany, myList ) =  List.take ( myList, toHowMany ) ;
val shorten = fn : int * 'a list -> 'a list

- shorten ( 2, [1,2,3,4,5,6] ) ;
val it = [1,2] : int list

Если порядок аргументов не имеет значения, то List.take можно использовать напрямую:

- List.take ( [1,2,3,4], 2 ) ;
val it = [1,2] : int list
person ben rudgers    schedule 27.10.2014