2014-10-19 2 views
1

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

Так fn [4,3,3,1,1,3,3,3] и [4,3,1, 3] вернется [4,3,1]

Это то, что я получил до сих пор, который просто возвращает пустой список

notEq'::[Int]->[Int] 
notEq' il = [x | x <- il, fn il] 
       where fn (a:b:xs) = a == b 

Edit: Расширение больше на вопрос, я хочу, чтобы сравнить каждый элемент к следующему и исключить последнее сравнение с []. Таким образом, [4,3,3,1] будет выглядеть примерно так (4,3, OK), (3,3, NO), (3,1, OK) с результатом [4,3]

+0

Это не ясно, если вы говорите, что вы _want_ его, чтобы исключить последний элемент, или что ваш текущий код делает это, и вы хотите исправить этот аспект. – DaoWen

+0

Простите, я уточнил это сейчас – bla9x

ответ

2

Функция, которую вы описываете, и пример, который вы дали, похоже, не согласны.

Пример вывода показывает, что вы ищете функцию, которая принимает список и возвращает список только отдельных элементов. В этом случае, вы ищете nub:

nub [4,3,3,1,1,3,3,3] 
-- result is [4,3,1] 

Однако функцию, которую вы описали на английском языке и в вашем коде принимает список и удаляет соседних дубликатов. В этом случае вы ожидаете, что результат для обоих входов будет [4,3,1,3], а не [4,3,1]. В этом случае, Haskell уже имеет функцию group подпоследовательностей соседних, равные элементы:

map head $ group [4,3,3,1,1,3,3,3] 
-- result is [4,3,1,3] 

Если вы должны использовать понимание, может быть, это будет достаточно:

[ x | x:xs <- group [4,3,3,1,1,3,3,3] ] 
-- result is [4,3,1,3] 

сейчас что вы уточнили, что вы хотите сделать, я думаю, tails будет вашим другом здесь:

let xs = [4,3,3,1,1,3,3,3] in 
    [ a | a:b:_ <- tails xs, a /= b ] 
-- result is [4,3,1] 

Я действительно не понимаю, почему вы хотите исключить последний элемент.Если вы случайно хотел включить его, было бы легко приспособить:

let [email protected](x:_) = [4,3,3,1,1,3,3,3] in 
    x : [ b | a:b:_ <- tails xs, a /= b ] 
-- result is [4,3,1,3] 
+0

Спасибо за это. И чтобы больше расширить вопрос, он сравнивает каждый элемент с другим и, кажется, исключает последнее сравнение с []. Таким образом, [4,3,3,1] будет выглядеть примерно так (4,3, OK), (3,3, NO), (3,1, OK) с результатом [4,3] – bla9x

1

Рассмотрим сжать каждый элемент списка с его преемником и фильтрации этих пар, первый и второй элемент отличается, как это,

notEq' :: [Int] -> [Int] 
notEq' xs = map (fst) . filter (\(a,b) -> a /= b) $ zip xs (drop 1 xs) 

Для получения списка с метками, рассмотрим это,

pairing :: Eq t => (t, t) -> (t, t, [Char]) 
pairing (x,y) = (x,y,label) 
    where 
    label = if (x /= y) then "OK" else "NO" 

и так

map (pairing) $ zip xs (drop 1 xs) 

для [4,3,3,1,1,3,3,3] поставит

[(4,3,"OK"),(3,3,"NO"),(3,1,"OK"),(1,1,"NO"),(1,3,"OK"),(3,3,"NO"),(3,3,"NO")] 

Update

Используя понимание, как это,

notEq' :: [Int] -> [Int] 
notEq' xs = [ x | (x,y) <- zip xs (drop 1 xs), x /= y ] 
Смежные вопросы