Daniel Fischer daniel.is.fischer at web.de
Mon Nov 3 18:53:05 EST 2008

```Am Dienstag, 4. November 2008 00:26 schrieb Michael Snoyman:
> On Mon, Nov 3, 2008 at 2:55 PM, Daniel Fischer
<daniel.is.fischer at web.de>wrote:
> > > class Multiplicable a b c where
> > >     mult :: a -> b -> c
> >
> > Use functional dependencies {-# LANGUAGE FunctionalDependencies #-},
> >
> > class Multiplicable a b c | a b -> c where ...
> >
> > which states that the result type of multiplication is determined by the
> > argument types
> >
> > or type families
>
> That's exactly what I was looking for, thank you. Now that I got that
> working, I've noticed that it can be tedious making sure the arguments to
> sumProduct are in the correct order. Since multiplication is commutative,
> is there any way of automatically having the Multiplicable instances
> generate a "flip" mult?

Beware! Multiplication is usually not commutative, think about matrices. If
(a `mult` b) and (b `mult` a) are both defined (need not be if they have
different types), the products may have different types, so in general it is
not desirable to have both defined automatically in a way that doesn't force
you to supply the arguments in the correct order.

In your case, you could provide
instance Multiplicable MilesPerGallon Gallon Mile where
mult = flip mult
-- or write the implementation out
and it should work whichever order the arguments are passed.

>
> > sumProduct :: (Addable c, Multiplicable a b c) => [a] -> [b] -> c
> >
> > > sumProduct x y = sum \$ product x y
> > >
> > > weightedAverage x y = (sumProduct y x) `divide` (sum y)
> > >
> > > class Dividable a b c where
> > >     divide :: c -> a -> b
> >
> > FunDep here, too, but which one?
>
> I did class Dividable a b c | c a -> b where...
>
> Michael

```