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
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe