Обновлено: Oops! Я пропустил последнюю часть вашего вопроса. То, что я объяснил, не работает, если вы попытаетесь добавить два разных типа, например Int + Double => Double
.
Я думаю, что вы можете использовать моноидными Scalaz «s
Просто, это выглядит как этот
trait Monoid[F] extends Semigroup[F] {
def zero: F
def append(f1: F, f2: => F): F
}
Так что, если вы хотите использовать его, все, что вам нужно сделать, это импортировать Scalaz
import scalaz._
import Scalaz._
Тогда вы можете просто сделать
1 |+| 1 // result: 2
"a" |+| "b" // result: ab
BigInt(100) |+| BigInt(100) // BigInt(200)
Scalaz обеспечивает неявное преобразование типов для большинства известных типов, таких как Int, BigInt, BigDecimal, String и т. Д., Но если у вас есть свой тип и вы хотите сделать его доступным, вы можете сделать это легко.
Допустим, у вас есть тип, как
case class Something(value: Int)
Вы можете использовать неявное преобразование типов, как.
implicit def SomethingMonoid = new Monoid[Something] {
override def zero: Something = Something(0)
override def append(f1: Something, f2: => Something): Something = Something(f1.value |+| f2.value) // you can even use |+| here as value is Int
}
Теперь, вы можете просто сделать
Something(10) |+| Something(100) // result: Something(110)
Если вы хотите использовать его, просто импортировать что SomethingMonoid с Scalaz
import scalaz._
import Scalaz._
import your.package.SomethingMonoid
// Or
import scalaz._
import Scalaz._
// ...
val somethingMonoid = your.package.SomethingMonoid
Затем вы можете сделать
Something(111) |+| Something(222) // result: Something(333)
Использование Monoid для обработки результата т лучше, чем иметь свой метод и вернуть Попробуйте [T], потому что вы не можете скомпилировать типобезопасность времени, тогда как Monoid даст вам ошибку во время компиляции, если вы делаете что-то подобное,
Something(10) |+| 100 // a compile-time error
Если вы действительно хотите иметь свой собственный плюс, вы можете сделать что-то вроде этого
def plus[T](x: T, y: T)(implicit monoid: Monoid[T]): Try[T] = Try(monoid.append(x, y))
с Scalaz, как я объяснил выше, но вы получите ошибку компиляции, когда типы не не совпадают так нет смысла использовать Попробуйте, если вычисление может бросить какое-то исключение.
plus(1, 2) // result: 3
plus(Something(1), Something(9)) // result: Something(10)
plus("one", 2) // result: a compile-time error
возможно дубликат [Scala - уборщик способ написания родовой числовой метод работы] (http://stackoverflow.com/questions/31346087/scala-cleaner-way-of-writing-generic-numeric-operation- метод) – Luegg
@Leugg - это было не так. У меня была двойная проблема. Первое - это отправка фактических параметров (во время компиляции типы всегда будут «Любые»), а затем для выполнения арифметической функции, как если бы компилятор знал типы динамически. Поэтому я хочу, чтобы плюс (1, 2.0) дал Double и plus (1, 2), чтобы получить Int –
. В этом случае я сомневаюсь, что есть простой и чистый способ делать то, что вы хотите. Используя 'Any', вы отменяете систему типов. Вы уверены, что связаны с «Любом» или есть способ сохранить исходные типы? Похоже, вы пытаетесь использовать Scala как язык динамических типов. – Luegg