I'm picking a specific task to illustrate what I was talking about
Let's say I wanted to find the sum of all the factors of a large number, naively -- by checking every number below it if it was a factor, then adding them together.
In an imperative programming language with no separation between IO and pure computations, you might do something like this
def sum_of_factors(n):
sum = 0
for i between 1 and n:
if (n % i == 0):
sum += i
return sum
However if my n
is large, I'd end up staring at an empty screen for a long time before the computation finishes. So I add some logging --
def sum_of_factors(n):
sum = 0
for i between 1 and n:
if (i % 1000 == 0):
print "checking $i..."
if (n % i == 0):
print "found factor $i"
sum += 1
return sum
and really, this addition is trivial.
Now, if I were to do this in textbook haskell i might do
sum_of_factors :: Int -> Int
sum_of_factors n = foldl' (+) 0 factors
where
factors = filter ((== 0) . (mod n)) [1..n]
I run into the same problem as before...for large numbers, I just stare at a blank screen for a while.
But I can't figure out how to inject the same kind of tracing/logging in the Haskell code. i'm not sure, other than maybe re-implementing fold with explicit recursion, to get the same tracing pattern/result as in the imperative impure code.
Is there a faculty in Haskell to make this doable? One that doesn't require refactoring everything?
Thank you