Являются ли кортежи строгими в haskell? - PullRequest
3 голосов
/ 23 апреля 2020

Если возникают проблемы с пониманием того, почему код ниже не останавливается, когда я запускаю его на 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 будет вызываться несколько раз с увеличивающимися номерами в одном и том же списке, поэтому я могу опускать головы при проверке.

1 Ответ

8 голосов
/ 23 апреля 2020

Вы видите артефакт 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 - посмотрим, что они скажут.

...