Haskell 中的元组是否严格?

lsm*_*mor 3 recursion haskell pattern-matching repl.it

如果在理解为什么我在 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
Run Code Online (Sandbox Code Playgroud)

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

-- 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

Run Code Online (Sandbox Code Playgroud)

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

如果你想知道,这个想法是isin在同一个列表中随着数字的增加而多次调用,所以我可以在检查时掉头。

Jos*_*ica 8

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

import Control.Concurrent
mapM_ (\i -> threadDelay 1000000 *> print i) [1..10]
Run Code Online (Sandbox Code Playgroud)

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

[0..]
Run Code Online (Sandbox Code Playgroud)

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

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

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