【问题标题】:Are tuples strict in haskell?元组在haskell中是严格的吗?
【发布时间】:2020-08-07 01:55:52
【问题描述】:

如果无法理解为什么我在 repl.it 上运行下面的代码时它不会停止。

-- The second argument is meant to be an infinite ascending list, don't bother yourself with any other case
isin :: Int -> [Int] -> (Bool, [Int])
isin n []       = (False, []) -- This case is unnecessary because the list is infinite, but just for completion
isin n l@(x:xs) =
  case n `compare` x of
    LT -> (False, l)
    EQ -> (True, xs)
    GT -> isin n xs

>>> isin 2 [1..]
-- prints nothing              --Edit
-- expected (True, [3,4,5...   --Edit

在我看来,这个的执行应该是这样的:

-- underscore is meant to be "unevaluated". (Probably not 100% accurate but you can follow my idea)

isin 2 1:_      -- first call 
  2 `compare` 1 -- GT
  isin 2 _

isin 2 2:_      -- second call
  2 `compare` 2 -- EQ
  (True, _)

(True, 3:_)     -- returned result

AFAIK,这应该可以正常工作,除非元组是严格的,在这种情况下我将使用不同的结构......但我 90% 确定它们不是

如果您想知道,这个想法是 isin 将在同一个列表中被多次调用,并且数字越来越多,所以我可以在检查时低头。

【问题讨论】:

  • 无法复制。当我运行它时,我得到(True,[3,4,5,6,7...
  • 等等。您是否将“无限长输出”与“永远运行”混为一谈?它们不是一回事。
  • 元组并不严格,但打印是。当您将表达式输入 ghci 时,您是在要求 ghci 打印它。为了打印一对,ghci 必须首先打印左侧组件(简单且短),然后打印右侧组件(也简单,但很长......)。尝试仅打印左侧组件,或仅打印右侧组件的前 10 个元素,以查看是否返回 ghci 提示符。
  • 如果您调用fst (isin 2 [1..]),它将终止。问题是元组的第二个值是一个无限列表,所以它不能完全打印第二部分。它将永远运行。
  • @JosephSible-ReinstateMonica 实际上我正在使用在线回复:repl.it/languages/haskell 以便向同事展示。所以我不知道它的配置

标签: haskell recursion pattern-matching repl.it


【解决方案1】:

您正在看到 repl.it 的工件。在您计算机上的 GHCi 中,这将按照您的预期运行。特别是, repl.it 在生成所有输出之前似乎不会向您发送任何输出。这里有两个例子可以证明这一点:

import Control.Concurrent
mapM_ (\i -> threadDelay 1000000 *> print i) [1..10]

如果你在 repl.it 上运行它,10 秒内什么都不会发生,然后你会突然恢复所有 10 个数字。如果您在计算机上的 GHCi 上运行它,那么您将在 10 秒内每秒获得一个数字。

[0..]

如果你在 repl.it 上运行它,它永远不会返回任何东西。如果您在计算机上的 GHCi 上运行它,您将获得所有自然数的永无止境的流。

有趣的是,这似乎只发生在您从控制台/终端(右侧)运行的代码中。如果您将所有代码放在一个文件中(左侧)并使用运行按钮,那么它的工作方式与在本地运行相同。

我在https://repl.it/bugs/p/consoleterminal-doesnt-show-output-until-the-end 上发布了这个消息 - 我们会看看他们怎么说。

【讨论】:

  • 谢谢我已经编辑了我期待(True, [1,2,3...) 而不是什么都没有的事实。所以当我说“永远运行”时,我的意思更清楚了
猜你喜欢
  • 1970-01-01
  • 2017-03-29
  • 2017-09-25
  • 1970-01-01
  • 2014-12-14
  • 2011-11-28
  • 2012-11-12
  • 1970-01-01
  • 2015-08-06
相关资源
最近更新 更多