Отсутствует первый элемент из списка вывода в Haskell - PullRequest
2 голосов
/ 30 сентября 2019

Я новичок в Haskell, и мне не хватает концепции при использовании Ord. Я пытаюсь вывести уникальные пары из списка в Haskell с помощью функции ниже

pairs:: (Ord a) => [a] -> [(a,a)]
pairs[] = []
pairs(x:xs) = [(i, j) | i <- xs, j <- xs, i > j]

Так, например, если я хочу получить уникальные пары из [4,3,1,2], я должен получитьвывод [(4,3), (4,1), (4,2), (3,1), (3,2), (2,1)]

но я получаю [(3,1), (3,2)] вместо.

мой вопрос: почему пропускается первый элемент списка xs?

Спасибо.

1 Ответ

7 голосов
/ 30 сентября 2019

Мой вопрос: почему это пропускает первый элемент списка xs?

Это не пропускает первый элемент списка xs. Это просто пропуск 1007 *. (x:xs) - это шаблон, где x - это «заголовок» списка (первый элемент), тогда как xs - это хвост списка (список, содержащий остальные элементы).

Таким образом, вы, вероятно, захотите использовать:

pairs:: (Ord a) => [a] -> [(a,a)]
pairs <b>xs</b> = [(i, j) | i <- xs, j <- xs, i > j]

Здесь мы, таким образом, собираем весь список xs.

Если порядок не имеет большого значения, мы можем сделать этонемного эффективнее, вычисляя минимум и максимум и повторяя хвосты:

import Data.List(tails)

order2 :: Ord a => a -> a -> (a, a)
order2 x y | x > y = (x, y)
           | otherwise = (y, x)

pairs:: (Ord a) => [a] -> [(a,a)]
pairs <b>xs</b> = [order2 i j | (i:js) <- tails xs, j <- js, i /= j]

Здесь мы, таким образом, сначала берем элемент i, а остальные элементы сохраняются в js. Затем мы перебираем js. Если i и j не совпадают, мы используем order2, чтобы создать 2-кортеж, в котором первый элемент больше, чем второй.

...