Thanks. That's interesting (but a little beyond me). Seems like he's
assuming that values beyond his range are zero whereas I'm trying to use
the values at the edges of the range.
Is there anything I can do before I understand comonads? ;-)
Michael
Dan Weston wrote:
There's an interesting blog post by Dan Piponi on the subject:
http://sigfpe.blogspot.com/2007/01/monads-hidden-behind-every-zipper.html
Summary: "convolution is comonadic"
Dan
Michael Feathers wrote:
I'm working on something and it's looking rather ugly.. essentially,
it it's an application of a low pass filer to a dataset.
type Dataset = [Double]
type FilterWindow3 = (Double,Double,Double)
internalList :: [a] -> [a]
internalList = tail . init
lowPass3 :: FilterWindow3 -> Double
lowPass3 (i, j, k) = (i + 2 * j + k) / 4.0
filter3 :: (FilterWindow3 -> Double) -> Dataset -> Dataset
filter3 f3 ds = [(f3 x) | x <- formWindows ds]
iterFilter :: (Dataset -> Dataset) -> Int -> Dataset -> Dataset
iterFilter f n ds
| n > 0 = iterFilter f (n - 1) (f ds)
| otherwise = ds
smooth :: Int -> Dataset -> Dataset
smooth = iterFilter $ filter3 lowPass3
formWindows :: Dataset -> [FilterWindow3]
formWindows ds =
internalList $ zip3 x y z
where c0 = [head ds]
cn = [last ds]
x = ds ++ cn ++ cn
y = c0 ++ ds ++ cn
z = c0 ++ c0 ++ ds
The key idea is that I can take care of edge conditions with that last
function. It lets me build a list of 3-tuples, each of which is
reduced to a single point in the next rewrite of the dataset. I used
zip3 to build up that list, and I take care to keep the lists the same
length by duplicating the head and last elements as necessary. Has
anyone done this sort of thing before?
Any and all style advice welcome.
Thanks,
Michael Feathers
--
Now Playing: http://www.youtube.com/watch?v=SsnDdq4V8zg
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe