Что такое идиоматический способ добавления списков в Haskell?

Предположим, я хочу добавить два списка в Haskell. Каков самый обычный способ сделать это?

Вот что я сделал:

addLists :: (Integral a) => [a] -> [a] -> [a]
addLists xs ys = map add $ zip xs ys
    where add (x, y) = x+y

Ответ 1

Существует функция zipWith, которая объединяет два списка с помощью поставляемой функции. Он делает именно то, что вы хотите здесь, и вы получаете:

addLists = zipWith (+)

Это использует (+) для объединения элементов списков, указанных в качестве дополнительных аргументов.

Ответ 2

Аппликативный стиль функтора:

import Control.Applicative

addLists xs ys = getZipList $ (+) <$> ZipList xs <*> ZipList ys

Обратите внимание, что это так уродливо, потому что есть два способа сделать список Аппликативным Functor. Первый (и IMHO менее полезный) способ состоит в том, чтобы взять все комбинации, и таким образом стал "стандартным", поэтому (+) <$> [1,2] <*> [30,40] - [31,41,32,42]. Другим способом является zip-списки, которые нам нужны здесь, но поскольку у вас может быть только один экземпляр класса типа для каждого типа, мы должны обернуть списки в ZipLists и развернуть результат с помощью getZipList.

Ответ 3

addLists xs ys = zipWith (+) xs ys