For the real-world-frege project I did the exercise from real-world-haskell where the assignment is to create a length function for lists and to compare it against the internal length function.
My proposed solution is under https://github.com/Dierk/Real_World_Frege/blob/master/realworld/chapter3/I_Exercise_1.fr
The beef of it is:
mylength :: [a] -> Int
mylength (_:xs) = 1 + (mylength xs)
mylength [] = 0
-- optLength uses tail recursion and forces eager argument evaluation
optLength xs = privateLength xs 0 where
privateLength (_:rest) !count = privateLength rest (count + 1)
privateLength [] !count = count
main _ = do
assert (mylength []) (length []) "empty"
assert (mylength [0]) (length [0]) "one element"
-- assert (mylength [0..30_000]) (length [0..30_000]) "many elements lead to stack overflow"
assert (optLength [0..1_000_000]) (length [0..1_000_000]) "optLength can do a little more"
assert (optLength [0..10_000_000]) (length [0..10_000_000]) "this takes 40 seconds (20 s each)"
-- println (length [0..100_000_000]) -- never stops
Both my and the internal length function work fine for lists under 1 million entries, get very slow with 10 M and appear to not stop at all for 100 M.
Frege's internal length function (not Haskell's) appears to have an upper limit below 100 million. Is that so?