Стандарт МЛ: как пролистать список? - PullRequest
0 голосов
/ 27 марта 2020

Я пытаюсь написать программу, которая просматривает список n раз. Предположим, что L = [a1, a2, ..., an] Я пытаюсь достичь [ai + 1, a i + 2, ..., an, a1, a2, ..., ai].

Я ссылался на предыдущий пост об этой точной проблеме. Однако я не уверен, как получить вывод или [ai + 1, a i + 2, ..., an, a1, a2, ..., ai].

Для вывода: I пробный цикл ([1,2,3,4], 5);

Однако ошибка, которую я получаю, заключается в том, что операнд и оператор не совпадают

Это код, который я нашел из предыдущего поста:

fun cycle n i = 
if i = 0 then n
else cycle (tl n) (i-1) @ [hd(n)];

1 Ответ

0 голосов
/ 27 марта 2020

Способ сделать это с помощью if-then-else:

fun cycle xs n =
    if n = 0
    then []
    else xs @ cycle xs (n - 1)

Вместо этого вы можете использовать сопоставление с шаблоном:

fun cycle xs 0 = []
  | cycle xs n = xs @ cycle xs (n - 1)

Но я думаю, что самое элегантное решение , использует функции высшего порядка:

fun cycle xs n =
    List.concat (List.tabulate (n, fn _ => xs))

Несколько сложнее задача - написать cycle для ленивых списков, которые бесконечно циклически ...

datatype 'a lazylist = Cons of 'a * (unit -> 'a lazylist) | Nil

fun fromList [] = Nil
  | fromList (x::xs) = Cons (x, fn () => fromList xs)

fun take 0 _ = []
  | take _ Nil = []
  | take n (Cons (x, tail)) = x :: take (n - 1) (tail ())

local
  fun append' (Nil, ys) = ys
    | append' (Cons (x, xtail), ys) =
        Cons (x, fn () => append' (xtail (), ys))
in
  fun append (xs, Nil) = xs
    | append (xs, ys) = append' (xs, ys)
end

fun cycle xs = ...

где take 5 (cycle (fromList [1,2])) = [1,2,1,2,1].

...