Как получить доступ к элементу списка, который я добавил, с помощью оператора cons (:)? - PullRequest
7 голосов
/ 28 февраля 2012

Я новичок в Haskell (и функциональном программировании в целом), и мне было интересно, как я могу получить доступ к новому элементу, который я добавил в список, используя cons ( :) оператор?

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

ghci> let a = [1,2,3]
ghci> a!!0
1

Подсказка возвращает 1, значение первого элемента, круто. Теперь я добавляю новое значение в начало списка и пытаюсь получить к нему доступ:

ghci> 5:a
[5,1,2,3]
ghci> a!!0
1

Похоже, элементы списка не переиндексируются. Я пытался заставить работать отрицательный индекс и другие подобные вещи, но компилятор, похоже, не одобрял. Уроки, которые я читаю, просто пропускают, и я не смог найти ничего полезного в Интернете. Как мне получить значение "5" из списка?

Спасибо за помощь и извините, если это очень простой вопрос.

Ответы [ 4 ]

12 голосов
/ 28 февраля 2012

Эта идея лежит в основе функционального программирования: вы (обычно) не изменяете данные на месте. Таким образом, вы не добавляете элемент в список: вы создаете новый список без изменения старого.

Это позволяет делать много приятных вещей, например, обмениваться, потому что вы никогда не меняете старые данные и можете ссылаться на них. Но это также накладывает бремя, если вы привыкли к другим парадигмам программирования: вы должны изменить свой подход к вещам (и часто вам приходится менять свои структуры данных / алгоритмы, потому что они полагались на модификацию структуры данных на месте) .

В вашем примере просто дайте новое имя списку conssed:

let a = [1, 2, 3]
let b = 5:a
7 голосов
/ 28 февраля 2012

Ваше недоразумение является фундаментальным: минусы ничего не изменяют.

5:a (где a = [1,2,3]) оценивается как [5,1,2,3], и именно это показывает вам переводчик.

6 голосов
/ 28 февраля 2012

Позвольте мне проиллюстрировать с помощью (+), а также (:)

Prelude> 4+5
9
Prelude> let z = 5
Prelude> z
5
Prelude> 4+z
9
Prelude> z
5
Prelude> let y = 4+z
Prelude> y
9
Prelude> z
5

против

Prelude> let a = [1,2,3]
Prelude> a
[1,2,3]
Prelude> 5:a
[5,1,2,3]
Prelude> a
[1,2,3]
Prelude> let b = 5:a
Prelude> b
[5,1,2,3]
Prelude> a
[1,2,3]

Привязки, сделанные с помощью 'let', никогда не меняются, но можно создавать новые,Если новая привязка имеет то же имя, что и старая привязка, то старая привязка «затеняется», а не мутирует.

2 голосов
/ 28 февраля 2012

Списки неизменны:

Prelude> let xs = [1,2,3]
Prelude> 4:xs
[4,1,2,3]
Prelude> xs
[1,2,3]
Prelude> let ys = 4:xs
Prelude> ys
[4,1,2,3]

Если вы хотите изменить элементы структуры данных, используйте Массивы .

...