Seq does not force evaluation

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" 

It will take about 8 seconds to load my second data, and then about 3 seconds to complete the rest of the functions.

However, if I delete the display length data, it will flash

 "Generated Second Data" "Generated Ten Minute Bars" "Generated Combined" "Ran Algo" 

Then stop a bit until it goes through all the actual functions.

This was my understanding, having carried out there where I prevented a lazy assessment. Am I using them incorrectly?

+4
source share
2 answers

Yes. Two important points to consider: seq evaluates WHNF (normal form with a weak head), and secondData is a list. WHNF means that the data will be calculated in the external constructor itself, and the most external constructor for secondData is : (if it is not empty, then the constructor [] ). So

 secondData `seq` generateBars (barSize featureSet) secondData 

will only do enough work to determine if secondData an empty list or has at least one element.

length evaluates the spine of the list, which basically means that it determines how many items are in the list, going through the full structure. This means that length will work more than seq for lists with more than 1 element.

You can use deepseq (from deepseq ) to fully evaluate the list, but you may not need it. length and deepseq should completely traverse the list. If you do not need to know this information in advance, it will be wasted, as your consumer will also have to sort through the list. Depending on the consumer, this can also increase the storage space of the heap, because deepseq will force all the data structures to be created at first, but they will not be GC'd until the algorithm is complete.

+11
source

seq only amplifies values ​​in normal form with a small head; for lists, this means that it evaluates far enough to determine if the list matches [] or _:_ . Under the assumption based solely on names (since you did not give any types), this or something like that is what happens to you: it evaluates far enough to understand that β€œyes, there is no more data” .

The usual trick is to call seq along the length of the list or use deepseq .

+3
source

All Articles