Using existential types
oleg at pobox.com
oleg at pobox.com
Fri Oct 10 13:00:03 EDT 2003
Tim Docker wrote:
> > data ColDesc rowv = forall a.
> > ColDesc (rowv -> a) ([a] -> a) (a -> String)
> >
> > calculate :: [rowv] -> ColDesc rowv -> ([String],String)
> > calculate rs (ColDesc valf sumf fmtf) =
> > let vals = map valf rs in
> > (map fmtf vals, (fmtf.sumf) vals)
> This code only does the (rowv -> a) evaluation once
Sorry I didn't know of that requirement. The desired sharing can easily
be introduced:
> data Results = Results { formatted:: [String], aggregated:: String }
> type ColDesc rowv = [rowv] -> Results
> calculate :: [rowv] -> ColDesc rowv -> ([String],String)
> calculate rs transformer = (formatted res, aggregated res)
> where res = transformer rs
> rows = ["I","wish","to","define","a","report"]
> mapp g f = g . (map f)
> cols = [
> \rvs -> Results rvs "",
> \rvs -> let vals = map length rvs
> in Results (map show vals) (show$sum vals),
> \rvs -> let vals = map (\s -> length s * length s) rvs
> in Results (map show vals) (show$maximum vals)
> ]
> values = [ calculate rows col | col <- cols ]
If we just need to format one value, we can write
> format_value v transformer = formatted $ transformer [v]
Due to laziness, the aggregate function will not be computed, unless
specifically requested.
More information about the Haskell-Cafe
mailing list