【问题标题】:Haskell + Infinite lists = HangHaskell + 无限列表 = 挂起
【发布时间】:2018-06-25 15:20:35
【问题描述】:

我正在学习 Haskell,阅读了一些参考资料,并且正在应对各种挑战(主要是代码战)。但是有时我会尝试为某些数学算法生成一个无限列表,然后从中进行选择(例如获取与某些模式匹配的前 n 个数字)。

但是,由于我的语法并不完美,我经常混淆部分,虽然我想要求 Haskell 定义(惰性)一个无限列表并选择前 5 个元素(或其他),但我最终实际上要求它做某事使用完整的无限列表,当我构建测试它时,程序只是挂起。

我设法(一次)调用了 Windows 进程管理器,发生的情况是,在 Visual Studio Code 中,当它构建和执行可执行文件时,它会以极快的速度增长,吸收所有内存和处理器,直到计算机变得无响应。

是否有某种编译器标志可以防止这种情况发生?

【问题讨论】:

  • 一般是impossible to determine if a program will ever terminate,所以编译器无法真正帮助你。你最好的办法是注意到它已经挂断并强行终止它。
  • 当您试验 Haskell 代码时,您可以在 GHCi 中运行它,直到您确信它可以工作为止。在 GHCi 中,如果执行似乎挂起,您可以中断Here's how to do it on Windows.
  • 使用 RTS 选项设置最大堆大小可能很有用,例如,+RTS -M128m -RTS。有关如何在编译时进行设置的信息,请参阅 the manual
  • 不确定如何提供帮助,但请尝试想想您的函数对列表的实际作用。 reverse 自然需要整个列表才能终止,sort 也是如此。 take 5 只需要检查前五个元素。
  • @RobertK,如果这样的想法要产生成效,将 Haskell 列表理解为“尾部可能是生成器的单链表”是必不可少的。

标签: haskell


【解决方案1】:

如 cmets 中所述,您可以使用 -M 开关运行可执行文件,该开关允许您指定最大内存大小。 (默认为无限制。)这样,如果您的程序尝试使用超过 X 量的内存,它将因异常而崩溃,而不仅仅是消耗所有可用的 RAM。

请注意,如果您的程序正在执行大量处理但并未尝试将结果实际保留在 RAM 中,那么这将无济于事。例如,如果您尝试打印出与条件匹配的第一个项目,但没有任何项目会匹配该条件,那么您的程序很可能会永远循环,但实际上不会消耗任何 RAM。在这种情况下,你只需要杀死它。

您也可以尝试在 GHCi 中运行您的代码,您只需按下 Ctrl+C 即可停止您的代码,而不会杀死 GHCi 本身。

【讨论】:

  • 谢谢,我已经开始结合使用 ghci、在编译器中设置限制以及真正尝试了解如何使用无限列表。
猜你喜欢
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 2015-01-10
  • 1970-01-01
  • 2013-03-13
  • 2012-10-04
  • 2018-01-14
  • 1970-01-01
相关资源
最近更新 更多