<div dir="ltr"><div><span style="font-family:arial,sans-serif;font-size:12.727272033691406px">> Actually I wonder why we don't have both Num and </span><span style="font-family:arial,sans-serif;font-size:13px"> Group, Ring, Field, etc...</span><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">
</div></div><div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div>There are mathy preludes if that's what you're into.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, May 21, 2014 at 3:03 PM, Giacomo Tesio <span dir="ltr"><<a href="mailto:giacomo@tesio.it" target="_blank">giacomo@tesio.it</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Actually I wonder why we don't have both Num and <span style="font-family:arial,sans-serif;font-size:13px"> Group, Ring, Field, etc...</span><div>
<div><font face="arial, sans-serif"><br></font></div><div>
<font face="arial, sans-serif">With </font><span style="font-family:arial,sans-serif;font-size:13px">GeneralizedNewtypeDeriving it would be awesome!</span></div><span class="HOEnZb"><font color="#888888"><div><font face="arial, sans-serif"><br>
</font></div></font></span><div><span class="HOEnZb"><font color="#888888"><font face="arial, sans-serif">Giacomo<br>
</font></font></span><div><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, May 21, 2014 at 7:01 PM, David Thomas <span dir="ltr"><<a href="mailto:davidleothomas@gmail.com" target="_blank">davidleothomas@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Yes, it "should" - in that it would be more expressive and allow types<br>


to catch more errors.  The current situation trades that away for<br>
reduced complexity.  Make whatever judgement call you want regarding<br>
whether that was appropriate.<br>
<div><div><br>
On Wed, May 21, 2014 at 9:57 AM, Dimitri DeFigueiredo<br>
<<a href="mailto:defigueiredo@ucdavis.edu" target="_blank">defigueiredo@ucdavis.edu</a>> wrote:<br>
> Thanks, the realization that price, cost and volume are different quantities<br>
> is exactly what led me to play around with the Units library.<br>
><br>
> I have a problem with Num. Shouldn't it be broken up into the fundamentals<br>
> of abstract algebra: Group, Ring, Field, etc? Just like is done for<br>
> Functors,<br>
> Applicative Functors, Monads, etc. It would avoid having the<br>
> typechecker allow me to multiply a Meter by Meter to get another Meter<br>
> (instead of the correct unit Meter^2).<br>
><br>
> Cheers,<br>
><br>
> Dimitri<br>
><br>
><br>
> Em 21/05/14 10:39, Brent Yorgey escreveu:<br>
><br>
>> Others have given examples of implementing this using a fold.  I'd<br>
>> like to point out something else: by representing all these prices and<br>
>> volumes etc. as a bare numeric type, you are simply asking for<br>
>> trouble!  The reason is that it allows many nonsensical operations.<br>
>> For example, you could add a price and a volume.  Adding a price and a<br>
>> volume makes no sense, but if they are the same type then the compiler<br>
>> cannot help you catch such a silly mistake.<br>
>><br>
>> I would do something like this:<br>
>><br>
>>    {-# LANGUAGE GeneralizedNewtypeDeriving #-}<br>
>><br>
>>    newtype Price = Price Double<br>
>>    -- you could also do  newtype Price a = Price a  if you want the<br>
>>    -- flexibility to be able to use any numeric type, though it's<br>
>>    probably not necessary.<br>
>><br>
>>    newtype Volume = Volume Double<br>
>>      deriving Num<br>
>>    newtype Cost = Cost Double<br>
>>      deriving Num<br>
>><br>
>> Notice I made a third type Cost, which is the result of multiplying a<br>
>> Price by a Volume.  If I understand the domain correctly, multiplying<br>
>> a Price by a Volume does not give you another Price (for example,<br>
>> would it make sense to multiply a Price by a Volume, and then take the<br>
>> result and multiply it by another Volume?).  A Price represents the<br>
>> value of a single share or unit of currency, whereas a Cost just<br>
>> represents some arbitrary amount of money.<br>
>><br>
>> Now, what sorts of operations can one do on these types?  Notice I put<br>
>> "deriving Num" after Volume and Cost, which means that two Volumes can<br>
>> be added or subtracted to give another Volume, and similarly for Cost<br>
>> (unfortunately, it means they can also be multiplied, which is<br>
>> probably not sensible, but that's more a failing of the Num class<br>
>> which is not granular enough).  We also should implement<br>
>><br>
>>    (.*) :: Price -> Volume -> Cost<br>
>>    Price p .* Volume v = Cost (p * v)<br>
>><br>
>> And now you can implement essentially any of the suggested solutions,<br>
>> but with more descriptive types like<br>
>><br>
>>    aggregate :: [(Price, Volume)] -> [(Cost, Volume)]<br>
>><br>
>> and using (.*) in the key place instead of (*).  And now the type<br>
>> checker will make sure you don't do silly things like add a Price and<br>
>> a Volume, or multiply a Cost by a Price!  Hooray!<br>
>><br>
>> -Brent<br>
>><br>
>> On Tue, May 20, 2014 at 08:12:59PM -0600, Dimitri DeFigueiredo wrote:<br>
>>><br>
>>> Awesome haskellers,<br>
>>><br>
>>> I am coding up a little function that aggregates "ask orders" in a<br>
>>> currency exchange.<br>
>>> Another way to look at it, is that the function takes as input a<br>
>>> histogram or fdf (in list format) and outputs the cumulative<br>
>>> distribution cdf (also in list format). So we are kind of<br>
>>> "integrating" the input list.<br>
>>><br>
>>> When given a list of asks in order of increasing price, the function<br>
>>> returns a list of points in the graph of the total supply curve.<br>
>>><br>
>>> Here's an example:<br>
>>><br>
>>> asks:                           returned list:<br>
>>><br>
>>> [ (Price 42, Volume 0.5),      [ (Price 21,         Volume 0.5),<br>
>>>    (Price 50, Volume  1 ),        (Price 21+50=71,   Volume 1.5),<br>
>>>    (Price 55, Volume 0.2)]        (Price 21+50+11=82,Volume 1.7)]<br>
>>><br>
>>> the returned list gives us the total supply curve (price = y-axis,<br>
>>> quantity/volume = x-axis, so the order is flipped)<br>
>>><br>
>>> Summarizing<br>
>>><br>
>>> * We're adding up the volumes. The last volume on the list is the<br>
>>> total volume available for sale.<br>
>>> * We calculate the total amount to be paid to buy the current volume<br>
>>> (for each item in the list).<br>
>>><br>
>>> I have written up a simple function to do this:<br>
>>><br>
>>> aggregate :: Num a => [(a,a)] -> [(a,a)]<br>
>>> aggregate xs = aggregate' 0 0 xs<br>
>>><br>
>>> aggregate' :: Num a => a -> a -> [(a,a)] -> [(a,a)]<br>
>>> aggregate' _ _ [] = []<br>
>>> aggregate' accX accY ((x,y):ls) = let accX' = accX + x * y<br>
>>>                                        accY' = accY +     y<br>
>>><br>
>>>                                        in  (accX',accY') : aggregate'<br>
>>> accX' accY' ls<br>
>>><br>
>>><br>
>>> main = print $ aggregate [(42,0.5),(50,1),(55,0.2)]<br>
>>><br>
>>> However, this does not look very good to me and it feels like I'm<br>
>>> reinventing the wheel.<br>
>>><br>
>>> Question: Is there a better Haskell way to do this? I'm really anal<br>
>>> about making it easy to read.<br>
>>><br>
>>> Thanks!<br>
>>><br>
>>> Dimitri<br>
>>> _______________________________________________<br>
>>> Beginners mailing list<br>
>>> <a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
>>> <a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
>><br>
>> _______________________________________________<br>
>> Beginners mailing list<br>
>> <a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
>> <a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
><br>
><br>
> _______________________________________________<br>
> Beginners mailing list<br>
> <a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
> <a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
</div></div></blockquote></div><br></div></div></div></div></div></div>
<br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div>