0
\$\begingroup\$

Objective:

  • Create a function to sum a list of fractions (represented as pairs)

Rules

  • Only Prelude functions allowed

Notes

  • I was debating if I should create a Fraction data type. Is it worth "upgrading" from a simple pair?
  • Is the code easy to follow and well-structured? How are my function names?
  • Is a simple error call a good way to inform the caller of incorrect arguments?

Code

sumOfFractions :: [(Integer, Integer)] -> (Integer, Integer)
sumOfFractions [] = error "empty list not allowed"
sumOfFractions fractions = reduce (numerator, lcd)
  where
    reduce (n, d) = (n `div` gcd_, d `div` gcd_)
    numerator = sum . map (\(x, y) -> x * (lcd `div` y)) $ fractions
    lcd = foldr1 lcm (map snd fractions)
    gcd_ = gcd numerator lcd 
\$\endgroup\$
1
\$\begingroup\$

There are two things that in my opinion would make your code easier to follow.

  1. 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.
  2. 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 simplify.
  • There's no need for an exception here, but I believe error is fine for this purpose in general.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.