
First, why do you think your code is non-optimal? you don't show your main program, so we don't know what you're measuring. Just by looking at some types (and not analysing the algorithm): 11 data FilterState a = FilterState { 14 , taps :: [a] -- current delay tap stored values the "State" really is "taps" only. (as and bs don't change ?) so "taps" should be separate. 25 newTaps = wk : init (taps s) "init" could be expensive (linear in the list length) (but you have linear cost elsewhere, so maybe it does not hurt) Use some different sequence type (instead of list)? It seems you actually want a strict sequence (while (:) is lazy) of strict values. 31 runFilter :: Kernel a -> FilterState a -> [a] -> IO ([a], FilterState a) why IO? there's no IO in the implementation. it looks like a simple fold. the type is polymorphic, so ghc needs to be able to inline the dictionary arguments. (I think that it means that it wants to "see" all the code when compiling main, but I'm not sure. Experts can tell by studing -ddump-simpl output.)