Simple Scala money library for some fun, I decided to start working on something that let me work with Money calculations. I realise there are libraries out there like Joda Money, but I'm doing this mainly for fun.

I was hoping to get a review on the way I've started to construct the library.

GitHub

private def calculate(that: Money)(f: (BigDecimal, BigDecimal) =&gt; BigDecimal): Either[String, Money] = (this.currency, that.currency) match {
case (c, c1) if c == c1 =&gt; new Right(this.copy(this.currency, f(this.amount, that.amount)))
case _ =&gt; new Left(Money.COMPARE_ERROR_MESSAGE)
}

private def compare(that: Money)(f: (BigDecimal, BigDecimal) =&gt; Boolean): Either[String, Boolean] = (this.currency, that.currency) match {
    case (c, c1) if c == c1 =&gt; new Right(this.amount &gt; that.amount)
    case _ =&gt; new Left(Money.COMPARE_ERROR_MESSAGE)
}


These two methods are incredibly similar except for the return type. Could someone suggest a way to improve this?
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
  }
}