How does Haskell tail recursion work?

后端 未结 6 1966
傲寒
傲寒 2020-12-07 15:30

I wrote this snippet of code and I assume len is tail-recursive, but a stack overflow still occurs. What is wrong?

myLength :: [a] -> Integer         


        
6条回答
  •  一个人的身影
    2020-12-07 16:14

    The simplest solution to your problem is turning on optimization.

    I have your source in a file called tail.hs.

    jmg$ ghc --make tail.hs -fforce-recomp
    [1 of 1] Compiling Main             ( tail.hs, tail.o )
    Linking tail ...
    jmg$ ./tail 
    Stack space overflow: current size 8388608 bytes.
    Use `+RTS -Ksize -RTS' to increase it.
    girard:haskell jmg$ ghc -O --make tail.hs -fforce-recomp
    [1 of 1] Compiling Main             ( tail.hs, tail.o )
    Linking tail ...
    jmg$ ./tail 
    10000000
    jmg$ 
    

    @Hynek -Pichi- Vychodil The tests above were done on Mac OS X Snow Leopard 64bit with a GHC 7 and GHC 6.12.1, each in a 32 bit version. After you're downvote, I repeated this experiment on Ubuntu Linux with the following result:

    jmg@girard:/tmp$ cat length.hs
    myLength :: [a] -> Integer
    
    myLength xs = len xs 0
        where len [] l = l
              len (x:xs) l = len xs (l+1)
    
    main = print $ myLength [1..10000000]
    
    jmg@girard:/tmp$ ghc --version
    The Glorious Glasgow Haskell Compilation System, version 6.12.1
    jmg@girard:/tmp$ uname -a
    Linux girard 2.6.35-24-generic #42-Ubuntu SMP Thu Dec 2 02:41:37 UTC 2010 x86_64 GNU/Linux
    jmg@girard:/tmp$ ghc --make length.hs -fforce-recomp
    [1 of 1] Compiling Main             ( length.hs, length.o )
    Linking length ...
    jmg@girard:/tmp$ time ./length 
    Stack space overflow: current size 8388608 bytes.
    Use `+RTS -Ksize -RTS' to increase it.
    
    real    0m1.359s
    user    0m1.140s
    sys 0m0.210s
    jmg@girard:/tmp$ ghc -O --make length.hs -fforce-recomp
    [1 of 1] Compiling Main             ( length.hs, length.o )
    Linking length ...
    jmg@girard:/tmp$ time ./length 
    10000000
    
    real    0m0.268s
    user    0m0.260s
    sys 0m0.000s
    jmg@girard:/tmp$ 
    
    

    So, if you're interested we can continue to find out what is the reason, that this fails for you. I guess, GHC HQ, would accept it as a bug, if such a straight forward recursion over lists is not optimized into an efficient loop in this case.

提交回复
热议问题