【问题标题】:Iterate over a list until the resulting list is an empty list迭代一个列表,直到结果列表是一个空列表
【发布时间】:2015-05-30 02:43:49
【问题描述】:

我正在尝试看看我是否可以这样做:

假设我有一个列表:[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]

【问题讨论】:

  • “通用解决方案”示例看起来像不相关的列表,令人困惑。这些列表不应该是[10,80,90,82,28] 的尾巴吗?

标签: haskell io-monad


【解决方案1】:

利用 IO monad 怎么样:

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]

如您所见herereturn 可以看作是“无操作”操作,绑定操作符>> 可以看作是在第二个操作之前执行第一个操作.

【讨论】:

  • 这成功了!如果没有人很快找到不需要函数定义的解决方案,我会接受。
【解决方案2】:

您可以使用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]

还要注意,您应该处理输入列表为空的情况。在当前的实现中,它会引发错误。

【讨论】:

  • 抱歉,我应该指定我正在寻找一种更通用的解决方案,一种我可以使用各种功能的解决方案。我会修改原来的问题
  • @ragesalmon 把它变成一个接受列表参数的函数是微不足道的。例如。 foo list = mapM_ print . init . tails $ tail list.
  • @ragesalmon,抱歉迟到了评论。当然,可以将此代码提取到单独的函数中。请看一下更新。
猜你喜欢
  • 1970-01-01
  • 2020-05-24
  • 2020-05-02
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 2022-06-27
  • 2021-09-22
  • 1970-01-01
相关资源
最近更新 更多