Подтвердить что ты не робот

Поверните список в Haskell

У меня есть список a,

let a = ["#","@","#","#"]

Как я могу повернуть @ два пробела, чтобы они закончились так?

["#","#","#","@"]

Я думал, что это может сработать,

map last init a

но, возможно, синтаксис должен быть другим, потому что карта может работать только с одной функцией?

4b9b3361

Ответ 1

Для полноты, версия, которая работает как с пустыми, так и с бесконечными списками.

rotate :: Int -> [a] -> [a]
rotate _ [] = []
rotate n xs = zipWith const (drop n (cycle xs)) xs

Тогда

Prelude> rotate 2 [1..5]
[3,4,5,1,2]

Ответ 2

Простое решение с использованием функции cycle, которая создает бесконечное повторение входного списка:

rotate :: Int -> [a] -> [a]
rotate n xs = take (length xs) (drop n (cycle xs))

затем

> rotate 2 ["#","@","#","#"]
["#","#","#","@"].

Ответ 3

Почему это осложняется?

rotate n xs = bs ++ as where (as, bs) = splitAt n xs

Ответ 4

Я очень новичок в haskell, поэтому ответ MGwynne был понятен. В сочетании с комментарием предлагающим альтернативный синтаксис, я попытался заставить его работать в обоих направлениях.

rotate :: Int -> [a] -> [a]
rotate n xs = take lxs . drop (n `mod` lxs) . cycle $ xs where lxs = length xs

Итак, rotate (-1) [1,2,3,4] дает тот же результат, что и rotate 3 [1,2,3,4].

Я думал, что мне пришлось добавить это, потому что drop ping меньше 0 элементов ничего не делает, поэтому мой предпочтительный ответ дает "неправильные" (по крайней мере, запутывающие) результаты с отрицательными значениями для параметра n.

интересная часть этого решения состоит в том, что он сочетает "полноту" для отрицательных поворотов с обработкой пустых списков. Благодаря ловкости Haskell он также дает правильные результаты для rotate 0 [].

Ответ 5

Начинающая попытка:

myRotate :: Int -> [String] -> [String]
myRotate 0 xs = xs
myRotate n xs = myRotate (n-1) (last xs : init xs)

Ответ 6

Не очень быстро для больших списков, но достаточно:

rotate :: Int -> [a] -> [a]
rotate n xs = iterate rot xs !! n
  where
    rot xs = last xs : init xs

Например:

> rotate 2 ["#","@","#","#"]
["#","#","#","@"]

Ответ 7

rotate :: Int -> [a] -> [a]
rotate n xs = drop k xs ++ take k xs
                where k = length xs - n

Эта функция вращается на n мест справа.

Ответ 8

rotate :: Int -> [a] -> [a]
rotate = drop <> take