Iterate produces stackoverflow errors

So, I just started with Frege and Haskell. I have experience working with functional languages ​​since I have been using Clojure for a couple of years now. The first thing I wanted to try was my usual approach to Fibonacci numbers.

next_fib (a, b) = (b, a + b)
fibs = map fst $ iterate next_fib (0, 1)
fib x = head $ drop x fibs

It happened in Frege. It works, but for very large numbers for fib, for example. (fib 4000), it throws StackOverflow errors. This surprised me because the same functions in Clojure will work fine. Is this Frege's mistake, or am I getting the whole lazy assessment wrong?

+4
source share
1 answer

, " ", .

GHC , Frege , , -, .

, Haskell awya thunks [. ], Frege - , . Haskell RTS , . Frege - JVM, , , . , JVM , , GHC.

- JVM , . . , , GHC , .

, "thunk". Thunk - - . , ,

(b, b+a)

(,) b {a+b}, { e } thunk, promises e . , thunk , , thunk , . ( , .)

, Frege Delayed<X>, Callable<X> memoization .

,

next_fib (next_fib (0, 1)) 

. :

(1, {0+1})

:

({0+1}, {1+{0+1}})

, thunks thunks, , next_fib , thunks, thunks , .

, , thunk 4000- , , , . , , , . , thunk thunks, , thunk. , 4000- , 4000 , .

, , :

(b; a+b)

thunks, . Haskell, , - :

let c = a+b in b `seq` c `seq` (b,c)

. , fib 4000 .

iterate, :

iterate f x = x : iterate f (f x)

[ x, f x, f (f x), f (f (f x)), ...]

, , , thunks!

, , , , ,

{f {f x}}

, thunk . , . frege online REPL try.frege-lang.org

frege> next (a,b) = (b; a+b) :: (Integer, Integer)
function next :: (Integer,Integer) -> (Integer,Integer)
frege> fibs = map fst $ iterate next (0,1)
function fibs :: [Integer]
frege> fib = (fibs!!)
function fib :: Int -> Integer
frege> map (length . show . fib) [0,500 ..]
[1,105,209,314,418,523,627,732,836,941,1045,1150,...]
frege> fib 4000
39909473435004422792081248094960912600792...

, , 500- ( REPL , ) ( ). , , 500 , , . , fib 4000! 6000 .

, head (!:):

a !: as = a `seq` (a:as)

, .

, fib. :

frege> iterate' f x = x !: iterate' f (f x)
function iterate' :: (a->a) -> a -> [a]
frege> fibs2 = map fst $ iterate' next (0,1)
function fibs2 :: [Integer]
frege> (length . show . (fibs2 !!)) 4000
836
frege> (length . show . (fibs2 !!)) 8000
1672
frege> (length . show . (fibs2 !!)) 16000
3344
frege> (length . show . (fibs2 !!)) 32000
6688
frege> (length . show . (fibs2 !!)) 64000
13375
frege> (length . show . (fibs2 !!)) 128000
java.lang.OutOfMemoryError: Java heap space

, 100 000 . , , 32 000 .

, :

fib :: Int -> Integer
fib n = go n 0 1 where
    go :: Int -> Integer -> Integer -> Integer
    go 0 !a !b = a
    go n !a !b = go (n-1) b (a+b)

, , .

(?) Clojure, - O (n), . , - , . 10000 :

frege> zzz = arrayFromList $ take 10000 $ map fst $ iterate (\(a,b) -> (b; a+b)) (0n,1)
function zzz :: JArray Integer
frege> elemAt zzz 4000
39909473435004422792081248094960912600792570982820257 ...

, . , O (1)

:

yyy = arrayCache f 10000 where 
       f 0 a = 0n
       f 1 a = 1n
       f n a = elemAt a (n-1) + elemAt a (n-2)
fib = elemAt yyy

, ..

, . , .

+7

All Articles