Как вы суммируете отдельные элементы пары в списке? - PullRequest
0 голосов
/ 06 марта 2019

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

func :: [(Double,Double)] -> (Double,Double)
func [(x, y)] = map fst (x,y)

1 Ответ

7 голосов
/ 06 марта 2019

Во-первых, давайте возьмем ваше текущее нерабочее определение:

func :: [(Double,Double)] -> (Double,Double)
func [(x, y)] = map fst (x,y)

В этом есть несколько ошибок:

  • Ваше совпадение с шаблоном [(x, y)] соответствует толькосписок с ровно одним элементом.Любой список с 2 или более элементами вызовет ошибку, поскольку они не совпадают.
  • map не может быть применено к кортежам;его можно применять только к спискам.
  • Даже если вы можете map над кортежем, fst должен применяться непосредственно к кортежу - fst (a, b) дает a, тогда как map fst (a, b) не делает 'не имеет смысла.

Давайте рассмотрим некоторые альтернативные определения.

Понимание списка

func_1 :: [(Double,Double)] -> (Double,Double)
func_1 list =
    let fsts = [ a | (a, _) <- list ]
        snds = [ b | (_, b) <- list ]
    in (sum fsts, sum snds)

Это отдельно выделяет каждый первый элемент из списка, затем каждую секундуэлемент из списка, затем складывает их вместе.

Отображение

func_2 :: [(Double,Double)] -> (Double,Double)
func_2 list =
    let fsts = map fst list
        snds = map snd list
    in (sum fsts, sum snds)

Карты fst над каждым элементом входного списка, чтобы получить список всех первых элементов списка.Затем сопоставьте snd, чтобы сделать то же самое для вторых элементов.

Рекурсия

func_3 :: [(Double,Double)] -> (Double,Double)
func_3 [] = (0, 0)
func_3 ((a,b) : xs) =
    let (a', b') = func_3 xs
    in (a+a', b+b')

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

  • Если в списке нет элементов, просто верните (0, 0) ( базовый случай ).
  • Если список имеетхотя бы один элемент, возьмите оставшуюся часть списка (например, [b, c], если было дано [a, b, c], или [], если было дано [a]), снова вычислите его сумму, используя func_3, затем добавьте первый элемент обратновкл.
...