seq not forcing evaluation

haskell

Solution

Yes. There are two important points to consider: `seq` evaluates to WHNF (weak-head normal form), and `secondData` is a list. WHNF means that the data will be evaluated to the outermost constructor, and the outermost constructor for `secondData` is `:` (unless it's empty, then the constructor is `[]`). So

secondData `seq` generateBars (barSize featureSet) secondData

will only do enough work to determine if `secondData` is the empty list, or if it has at least one element.

`length` evaluates the spine of a list, which basically means it determines how many elements are in the list by traversing the full structure. This means that `length` will do more work than `seq` for lists with more than 1 element.

You can use `deepseq` (from deepseq) to fully evaluate a list, but you may not want to. `length` and `deepseq` have to fully traverse the list. If you don't need to know that information in advance, this is wasted effort as your consumer will have to traverse the list again also. Depending on the consumer, this may also increase heap residency because deepseq will force all the data structures first, but they won't be GC'd until after the algorithm is complete.

Problem

So I have my haskell program that looks something like this: ``` main = do secondData <- loadSecondBars "output.data" putStrLn $ "Generated Second Data " ++ (show $ length secondData) let tenMinBars = secondData `seq` generateBars (barSize featureSet) secondData putStrLn $ "Generated Ten Minute Bars " ++ (show $ length tenMinBars) let combinedData = seq tenMinBars sortBars (tenMinBars ++ secondData) putStrLn $ "Generated Combined" ++ (show $ length combinedData) let completedOrderManager = evalState (runBar combinedData) startState putStrLn "Ran Algo" ``` Doing this it will take about 8 seconds to load my second data, then about 3 seconds to do the rest of the functions. However, if I remove the show length data, it will flash ``` "Generated Second Data" "Generated Ten Minute Bars" "Generated Combined" "Ran Algo" ``` Then pause for a bit till it runs through all the actual functions. It was my understanding by having seq in there I prevented the lazy evaluation. Am I using them wrong?

Original source