[Haskell-beginners] A better way to "integrate"
Zhi An Ng
ngzhian at gmail.com
Wed May 21 02:58:22 UTC 2014
Travesals can usually be implemented using folds, since your list is
increasing, I would think to use a foldl, this is my attempt:
foldl :: (a -> b -> a) -> a -> [b] -> a
prices = [(42, 0.5), (50, 1), (55, 0.2)]
agg = foldl accum []
where accum [] (price, volume) = [(price * volume, volume)]
accum xs (price, volume) =
let total = last xs
total_price = fst total
total_volume = snd total
cost = price * volume in
xs ++ [(total_price + cost, total_volume + volume)]
main = print $ agg prices
Best,
Zhi An
On Wed, May 21, 2014 at 10:12 AM, Dimitri DeFigueiredo <
defigueiredo at ucdavis.edu> wrote:
> Awesome haskellers,
>
> I am coding up a little function that aggregates "ask orders" in a
> currency exchange.
> Another way to look at it, is that the function takes as input a histogram
> or fdf (in list format) and outputs the cumulative distribution cdf (also
> in list format). So we are kind of "integrating" the input list.
>
> When given a list of asks in order of increasing price, the function
> returns a list of points in the graph of the total supply curve.
>
> Here's an example:
>
> asks: returned list:
>
> [ (Price 42, Volume 0.5), [ (Price 21, Volume 0.5),
> (Price 50, Volume 1 ), (Price 21+50=71, Volume 1.5),
> (Price 55, Volume 0.2)] (Price 21+50+11=82,Volume 1.7)]
>
> the returned list gives us the total supply curve (price = y-axis,
> quantity/volume = x-axis, so the order is flipped)
>
> Summarizing
>
> * We're adding up the volumes. The last volume on the list is the total
> volume available for sale.
> * We calculate the total amount to be paid to buy the current volume (for
> each item in the list).
>
> I have written up a simple function to do this:
>
> aggregate :: Num a => [(a,a)] -> [(a,a)]
> aggregate xs = aggregate' 0 0 xs
>
> aggregate' :: Num a => a -> a -> [(a,a)] -> [(a,a)]
> aggregate' _ _ [] = []
> aggregate' accX accY ((x,y):ls) = let accX' = accX + x * y
> accY' = accY + y
>
> in (accX',accY') : aggregate' accX'
> accY' ls
>
>
> main = print $ aggregate [(42,0.5),(50,1),(55,0.2)]
>
> However, this does not look very good to me and it feels like I'm
> reinventing the wheel.
>
> Question: Is there a better Haskell way to do this? I'm really anal about
> making it easy to read.
>
> Thanks!
>
> Dimitri
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20140521/65f10711/attachment.html>
More information about the Beginners
mailing list