Как переместить элемент в списке в Haskell?

Я читаю через узнать вы на Haskell и достиг места, где я пытаюсь переместить элемент в списке в голову. Я придумал то, что считаю наивным, и мне любопытно, может ли кто-нибудь показать мне, что опытный программист Haskell сделал бы вместо этого.

в этом примере у меня есть список целых чисел, и я хочу переместить элемент "4", который будет индексом "3", в начало списка.

let nums = [1, 2, 3, 4, 5]
(nums !! 3) : delete (nums !! 3) nums

возвращает [4, 1, 2, 3, 5].

что вы думаете?

5 ответов


Я бы сделал это так:

move n as = head ts : (hs ++ tail ts)
   where (hs, ts) = splitAt n as

splitAt разбивает список на заданную позицию, возвращает две части, которые создаются разбиением (здесь hs и ts). Элемент, который должен быть перемещен вперед, теперь находится в начале ts. head ts возвращает только первый элемент вектора ts, tail ts возвращает все но это первый элемент. Результат функции просто эти части объединены в правильном порядке:hs соединяется с tail ts и добавлено элементом head ts.


опытные Haskellers вряд ли когда-либо с помощью индексации списка. Я бы использовал break, чтобы избежать повторных обходов (предполагая, что вы хотите соответствовать элементу "4", а не индексу "3"):

case break (== 4)  [1, 2, 3, 4, 5] of
    (a,x:xs) -> x:a ++ xs
    (a,xs)    -> a ++ xs

в:

Prelude Data.List> case break (== 4)  [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs
[4,1,2,3,5]

мы можем сделать то же самое с индексированием через "splitAt":

Prelude Data.List> case splitAt 3  [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs
[4,1,2,3,5]

небольшая модификация решения sth:

toHead n xs = x : pre ++ post
  where (pre, x:post) = splitAt n xs

Использование шаблона вместо head n tail


там же

toHead n l = l !! n : take n l ++ drop (n+1) l

что может быть немного проще, чем использовать splitAt.


какое совпадение?
Я читал то же самое несколько дней назад. Посмотрел его снова и написал его, как следующее.

nums !! 3 : [x | x <- nums, (x == (num !! 3)) == False]