Debugging a stack overflow in haskell -


i'm new haskell , functional programming , have program works overflows stack after few seconds. question is, should here? how can @ least hint of occurs, print stack or anything?

the program slow when running in ghci :trace stack overflow not occur. not occur runhaskell eat more , more memory. error when compiling ghc , executing.

in case, strictness problem causing stack overflow. 1 easy way find such issues using deepseq library. adds few functions allow evaluate value (which better seq, goes 1 level down). key function force :: nfdata => -> a. takes value, evaluates it, , returns it.

it works on types implement nfdata type class though. luckily, there template haskell macro in deepseq-th library: derivenfdata. used own data types, eg derivenfdata ''bfmachine.

to use, put force $ in front of functions may having strictness problems (or liftm force $ monadic functions). eg code, put in front of step, since key function in file:

{-# language templatehaskell #-} import data.char import debug.trace import control.deepseq import control.deepseq.th import control.monad (liftm)  type stack = [int]  data bfmachine = bfmachine     { program :: string     , pc :: int     , stack :: stack     , sp :: int     } deriving show derivenfdata ''bfmachine  setelem :: [int] -> int -> int -> [int] setelem list n value = map (\(i, v) -> if == n value else v) (zip [0..] list)  step :: bfmachine -> io (bfmachine) step m@(bfmachine { program = program, pc = pc, stack = stack, sp = sp }) = liftm force $     case program !! pc of     '-' -> return m { pc = pc + 1, stack = setelem stack sp ((stack !! sp) - 1) }     '+' -> return m { pc = pc + 1, stack = setelem stack sp ((stack !! sp) + 1) }     '<' -> return m { pc = pc + 1, sp = sp - 1 }     '>' -> return m { pc = pc + 1, sp = sp + 1 }     '[' -> return $ if stack !! sp /= 0 m { pc = pc + 1 }                     else m { pc = (findnextbracket program $ pc + 1) + 1 }     ']' -> return m { pc = findprevbracket program $ pc - 1 }     '.' -> putchar $ chr $ stack !! sp               return m { pc = pc + 1 }     ',' -> c <- getchar               let s' = setelem stack sp $ ord c                  in return m { stack = s',  pc = pc + 1 }     -> return m { pc = pc + 1 }  findnextbracket :: string -> int -> int findnextbracket program pos =     case program !! pos of     '[' -> findnextbracket program $ (findnextbracket program $ pos + 1) + 1     ']' -> pos     x -> findnextbracket program (pos + 1)  findprevbracket :: string -> int -> int findprevbracket program pos =     case program !! pos of     ']' -> findprevbracket program $ (findprevbracket program $ pos - 1) - 1     '[' -> pos     x -> findprevbracket program (pos - 1)  isfinished :: bfmachine -> bool isfinished m@(bfmachine { program = p, pc = pc })     | pc == length p = true     | otherwise = false  run :: bfmachine -> io () run m =     if isfinished m         return ()     else         m <- step m         run m  fib = ">++++++++++>+>+[ [+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[ [-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<- [>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>> ]<<< ] program doesn't terminate; have kill it.  daniel b cristofani (cristofdathevanetdotcom) http://www.hevanet.com/cristofd/brainfuck/" main = run bfmachine { program = fib , pc = 0, stack = replicate 1024 0, sp = 0 } 

this solves problem - after few minutes running, hasn't crashed , memory usage 3.2mb.

you can stick solution, or try find real strictness problem (as makes strict). removing force step function, , trying on helper functions uses (eg setelem, findprevbacket, etc). turns out setelem culprit, putting force in front of function solves strictness problem. i'm guessing because if in map lambda means values never have evaluated in list, , possibly build huge thunks program continues.


Comments

Popular posts from this blog

wordpress - (T_ENDFOREACH) php error -

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

Using django-mptt to get only the categories that have items -