Here’s a simple program I wrote to test out if Haskell’s recursion within a do-block will stack overflow:
count :: Int -> IO Int
count it
| it <= 0 = pure 0
| otherwise =
do
n <- count (it - 1)
pure (n + 1)
surprisingly it doesn’t seem to stack overflow even for largish numbers like 1000000.
The equivalent Scala code in a for-comprehension:
import cats.effect.IO
val count: Int => IO[Int] = {
case 0 => IO.pure(0)
case it =>
for {
n <- count (it - 1)
} yield (n + 1)
}
count(10000).unsafeRunSync
stack overflows at numbers around 10,000.
My question is about how Haskell implements this recursion in a do block such that it doesn’t stack overflow. I presume it’s related to thunks, beyond that I am not sure how it works. Any help would be appreciated. I looked around Google but couldn’t find anything related… maybe I’m looking for the wrong keywords.
Thanks. Yes, for very large numbers it overflows. I was just wondering how it allows for such large numbers given that the Scala version can only support much smaller numbers.