There are two things that in my opinion would make your code easier to follow.
- The sum of zero numbers can be (and is usually) defined as zero, which is the identity element
0 of addition in the sense that
$$ x = 0 + x = x + 0$$
holds for all x.
- The sum of more than two numbers is perhaps best defined recursively, using the associativity property
$$ x + y + z = (x+ y) + z = x + (y + z).$$
One way to use these properties in code is the following.
type MyFraction = (Integer, Integer)
sumOfFractions :: [MyFraction] -> MyFraction
sumOfFractions = foldl plus (0, 1)
plus :: MyFraction -> MyFraction -> MyFraction
plus (a, u) (b, v) = (c `div` x, w `div` x)
where c = a*v + b*u
w = u*v
x = gcd c w
It should be a fun exercise to define a datatype so that
(+), and by extension
sum works on them. Type
t: (+) into an interpreter and go from there!
To answer your last two questions:
- Your function names are fine. Perhaps
reduce should be
- There's no need for an exception here, but I believe
error is fine for this purpose in general.