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