eelco.lempsink.nl responde a la pregunta que ha planteado. He aquí una demostración de la respuesta de Yann:
module Main
where
import Data.List
import System.Environment (getArgs)
main = do
n <- getArgs >>= readIO.head
putStrLn $ "Length of an array from 1 to " ++ show n
++ ": " ++ show (myLength [1..n])
myLength :: [a] -> Int
myLength = foldl' (const . succ) 0
foldl' pasa a través de la lista de izquierda a derecha cada vez añadiendo 1 a un acumulador que comienza en 0.
He aquí un ejemplo de cómo ejecutar el programa:
C:\haskell>ghc --make Test.hs -O2 -fforce-recomp
[1 of 1] Compiling Main (Test.hs, Test.o)
Linking Test.exe ...
C:\haskell>Test.exe 10000000 +RTS -sstderr
Test.exe 10000000 +RTS -sstderr
Length of an array from 1 to 10000000: 10000000
401,572,536 bytes allocated in the heap
18,048 bytes copied during GC
2,352 bytes maximum residency (1 sample(s))
13,764 bytes maximum slop
1 MB total memory in use (0 MB lost due to fragmentation)
Generation 0: 765 collections, 0 parallel, 0.00s, 0.00s elapsed
Generation 1: 1 collections, 0 parallel, 0.00s, 0.00s elapsed
INIT time 0.00s ( 0.00s elapsed)
MUT time 0.27s ( 0.28s elapsed)
GC time 0.00s ( 0.00s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 0.27s ( 0.28s elapsed)
%GC time 0.0% (0.7% elapsed)
Alloc rate 1,514,219,539 bytes per MUT second
Productivity 100.0% of total user, 93.7% of total elapsed
C:\haskell>
Solo quería apuntar: esta es una muy buena pregunta. La evaluación diferida tiene efectos secundarios interesantes que pueden no ser inmediatamente obvios para todos los programadores. – jrockway
Sí, trabajando en Haskell en comparación con otros lenguajes funcionales no puros, te das cuenta de que trucos estúpidos como reescribir para recursividad de cola a menudo son innecesarios o dañinos, y en su lugar debes dedicar tus esfuerzos a lo que realmente se necesita evaluar. – ephemient