2015-05-30 2 views
2

Я пытаюсь увидеть, если я могу сделать что-то вроде этого:Итерация по списку, пока результирующий список является пустым списком

Say У меня есть список: [1, 8, 90, 100, 82]

Теперь, что я хотел бы сделать что-то вроде этого

print [8, 90, 100, 82] 
print [90, 100, 82] 
print [100, 82] 
print [82] 

Так в основном, я хотел бы напечатать оставшуюся часть списка, пока я не получаю пустой список, а затем остановиться. Есть ли способ сделать это в Haskell?

EDIT: Я ищу более общее решение. Например, я хотел бы также, чтобы быть в состоянии произвести это:

список [10, 80, 90, 82, 28]

[70, 80, 72, 18] 
[52, 62, 54] 
[10, 2] 
[8] 
+1

Пример «общего решения» выглядит как несвязанные списки и запутан. Не должны ли эти списки быть хвостами '[10,80,90,82,28]'? – chi

ответ

6

насчет эксплуатируя IO монада:

func [_] = return() 
func (_:xs) = print xs >> func xs 

Когда один называет это это приводит:

*Main> func [1, 8, 90, 100, 82] 
[8,90,100,82] 
[90,100,82] 
[100,82] 
[82] 

Как вы можете прочитать here, то return можно рассматривать как операцию «без операции», а оператор привязки >> можно увидеть как выполнить первую операцию перед второй операцией.

+0

Это сработало! Если в ближайшее время никто не будет комментировать решение, которое не требует определения функции, я соглашусь с этим. – ragesalmon

6

Вы можете использовать функцию mapM_ для применения print для каждого элемента в списке. Существует функция tails, возвращает все конечные сегменты аргумента (однако он также возвращает пустой список как последний элемент, поэтому вы можете объединить его с функцией init). Наконец, вы можете пропустить первый элемент, если вы не хотите, чтобы напечатать ее, используйте функцию tail:

import Data.List 

main :: IO() 
main = mapM_ print . init . tails $ tail [1, 8, 90, 100, 82] 

Печать:

[8,90,100,82] 
[90,100,82] 
[100,82] 
[82] 

Конечно, можно решить проблему, используя отдельные функции , Обратите внимание, что я добавить еще две функции, чтобы сделать код более читаемым и многоразовые:

import Data.List 

tailsExceptOriginalAndEmpty :: [a] -> [[a]] 
tailsExceptOriginalAndEmpty = init . tails . tail 

printListofLists :: (Show a) => [[a]] -> IO() 
printListofLists = mapM_ print 

printTailsExceptOriginalAndEmpty :: (Show a) => [a] -> IO() 
printTailsExceptOriginalAndEmpty = printListofLists . tailsExceptOriginalAndEmpty 

main :: IO() 
main = printTailsExceptOriginalAndEmpty [1, 8, 90, 100, 82] 

Отметим также, что вы должны обрабатывать случай с пустым списком ввода. В текущей реализации это вызовет ошибку.

+0

Извините, я должен был указать, что я ищу более общее решение, для которого я мог бы использовать множество функций. Я исправлю исходный вопрос – ragesalmon

+1

@ragesalmon Включение этого в функцию, которая принимает параметр списка, тривиальна. Например. 'foo list = mapM_ print. в этом . хвосты $ tail list'. – chi

+1

@ragesalmon, извините за поздний комментарий. Конечно, этот код можно разделить на отдельные функции. Пожалуйста, взгляните на обновление. – soon

 Смежные вопросы

  • Нет связанных вопросов^_^