Simple Scala money library
First thoughts:


If an operation can fail, it is generally good practise to make this explicit in the API by returning a Try instead of an Either.
The duplicate code seems to stem from the fact that Money operations are only valid on Currencies of the same type. Scala gives you the power to have this check at compile time.


Example Code:

object Money {
  sealed trait Currency
  case object GBP extends Currency
}
case class Money[T &lt;: Money.Currency](amount: BigDecimal) {
  private def calculate(that: Money[T])(f: (BigDecimal, BigDecimal) =&gt; BigDecimal): Money[T] = {
    copy(amount = f(this.amount, that.amount))
  }
  private def compare(that: Money[T])(f: (BigDecimal, BigDecimal) =&gt; Boolean): Boolean = {
    this.amount &gt; that.amount
  }
}