Haskell: создать список последних элементов каждого списка в списке - PullRequest
1 голос
/ 31 марта 2019

Мне нужно определить функцию в Haskell's, которая для заданного списка списков создаст список его последних элементов.Например, для [[1,2],[3,4]] должно возвращаться [2,4]

Я пытался использовать сопоставление с образцом, но ite возвращает только последний список:

lastElement :: [[a]] -> [a]
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs

это дает мне [3,4]

Ответы [ 2 ]

6 голосов
/ 31 марта 2019

Проблема

Вы на правильном пути, проблема в том, что ваш код не повторяется.Рекурсивная функция в списках обычно имеет вид

f :: [a] -> [b]
f [] = y
f (x:xs) = y : f xs

После оценки y этот результат ": ed" для рекурсивного вызова.Теперь попробуйте сделать ваш код таким же.Также обратите внимание, что вам не нужен случай lastElement [x], он просто избыточен для рекурсии.Однако, это только применяет некоторую функцию к каждому элементу.Вам также понадобится функция f :: [a] -> a, чтобы получить этот последний элемент из одного списка.Ваша функция на данный момент делает именно это, но для этого есть стандартная библиотечная функция.Посмотрите на Hoogle : вы можете искать библиотечные функции по типу или описанию

Лучшая альтернатива

В этом случае я бы использовал понимание списка, как мне кажется,быть более понятным для чтения.Взгляните также на это

Лучшая альтернатива

Функциональный язык Haskell позволяет вам больше думать о том, какие изменения нужно применить к вашим данным, а не какие шаги вы делаетенужно добиться.Если вы их знаете, вы можете использовать для этого функцию более высокого порядка.В частности, функция map :: (a -> b) -> [a] -> [b].Как вы можете догадаться из этого определения типа, map берет функцию и применяет ее к каждому элементу списка.Похоже, вы уже знаете функцию last, поэтому вы можете использовать ее:

lastElements :: [[a]] -> [a]
lastElements = map last

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

1 голос
/ 31 марта 2019

Я предполагаю, что у вас есть навыки новичка в Хаскеле, и постараюсь лучше объяснить, что вы делаете неправильно.

lastElement :: [[a]] -> [a]
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs

В этой функции вы получаете список элементов и возвращаете последний из них. Случается, что эти элементы тоже списки. Таким образом, применение lastElement [[1,2],[3,4]] даст вам его последний элемент, как выглядит список [3,4]. Поскольку вам нужно ввести список [x,y,z], в котором x y и z являются списками, а вы хотите вернуть [last of x, last of y, last of z], нам понадобятся две вещи:

1. Функция, которая получает список Int и возвращает его последний элемент

2. Применить эту функцию к (списку (спискам)) [[a]]

Чтобы сделать (1) , мы можем легко изменить вашу функцию lastElement следующим образом:

lastElement :: [a] -> a
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs

Теперь lastElement получает один список и возвращает свой последний элемент.

Чтобы сделать (2) , нам просто нужно создать функцию отображения, подобную этой:

mapping :: ([a] -> a) -> [[a]] -> [a]
mapping _ [] = []
mapping f (x:xs) = (f x) : (mapping f xs)

Таким образом, вы можете позвонить mapping lastElement [[1,2],[3,4]], который даст вам [2,4].

Мне нужно сказать, что ничего из этого не требуется, если вы знали две последние функции, которые выполняют те же действия, что и (1) , и карту, выполняющую то же самое, что и (2) * 1039. *. Зная это, вы можете сделать как Лоренцо , уже сделанное выше:

lastElements :: [[a]] -> [a]
lastElements = map last
...