2015-05-30 81 views
2

我想看看我能不能做這樣的事情:迭代一個列表,直到結果列表是空列表

說我有一個清單:1,8,90,100,82]現在

,我想要做的就是這樣的事情

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

所以基本上,我想打印列表的其餘部分,直到我得到一個空列表,然後停止。有什麼方法可以在Haskell中做到這一點?

編輯:我正在尋找更一般的解決方案。例如,我還希望能生產這樣的:

列表[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。在裏面 。尾巴$尾列表「。 – chi

+1

@ragesalmon,對於遲到的評論感到抱歉。當然,可以將這些代碼提取到不同的函數中。請看看更新。 – soon