haskell 中的元组是否严格?

Are tuples strict in haskell?

如果我无法理解为什么当我 运行 它在 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 将在同一个列表中随着数字的增加而被多次调用,所以我可以在检查时掉头。

您看到的是 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 上,它永远不会 return 任何东西。如果你 运行 它在你计算机上的 GHCi 上,你将得到一个永无止境的所有自然数流。

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

我在 https://repl.it/bugs/p/consoleterminal-doesnt-show-output-until-the-end 发布了有关此内容的信息 - 我们将看看他们怎么说。