부울뿐만 아니라 다양한 숫자 형식의 값을 저장하는 클래스 C
을 구현하고 싶습니다. 또한,이 클래스의 인스턴스를 필요에 따라 Int --> Double
및 Boolean -> Int
으로 변환 할 수 있습니다. 즉, Boolean + Boolean
, Int + Boolean
, Boolean + Int
, Int + Double
, Double + Double
등을 추가 할 수 있고 가능한 한 가장 작은 값을 반환 할 수 있습니다. 가능할 때마다 (Int
또는 Double
)를 입력하십시오.숫자 형식 간의 산술을 허용하는 암시 적 변환을 설정하는 방법?
지금까지 나는이 함께했다 :
이 경우 작동abstract class SemiGroup[A] { def add(x:A, y:A):A }
class C[A] (val n:A) (implicit val s:SemiGroup[A]) {
def +[T <% A](that:C[T]) = s.add(this.n, that.n)
}
object Test extends Application {
implicit object IntSemiGroup extends SemiGroup[Int] {
def add(x: Int, y: Int):Int = x + y
}
implicit object DoubleSemiGroup extends SemiGroup[Double] {
def add(x: Double, y: Double):Double = x + y
}
implicit object BooleanSemiGroup extends SemiGroup[Boolean] {
def add(x: Boolean, y: Boolean):Boolean = true;
}
implicit def bool2int(b:Boolean):Int = if(b) 1 else 0
val n = new C[Int](10)
val d = new C[Double](10.5)
val b = new C[Boolean](true)
println(d + n) // [1]
println(n + n) // [2]
println(n + b) // [3]
// println(n + d) [4] XXX - no implicit conversion of Double to Int exists
// println(b + n) [5] XXX - no implicit conversion of Int to Boolean exists
}
(1, 2, 3)하지만하지 않습니다 (4, 5). 그 이유는 형식이 낮은 것부터 높은 것까지 묵시적으로 넓어 지지만 다른 방법은 아닙니다.
def +[T, A <% T](that:C[T]):T = that.s.add(this.n, that.n)
하지만 컴파일러가 this.n
변환 할 수 없습니다 먼저 것으로, 두 가지 이유가 컴파일되지 않습니다 : 방법,
def +[T <% A](that:C[T]) = s.add(this.n, that.n)
어떻게 든 같이 보일 것이다 파트너 방법을 가질 필요가 방법에 두 번째로 this.n
을 변환 할 수 있다고해도 형식 지우기 후에 두 개의 +
메서드가 모호 해집니다.
죄송합니다. 너무 오래되었습니다. 어떤 도움을 많이 주시면 감사하겠습니다! 그렇지 않으면 명시 적으로 모든 유형 간의 모든 작업을 작성해야합니다. 그리고 여분의 유형을 추가해야한다면 털이 될 것입니다 (Complex
은 메뉴 옆에 있습니다 ...).
누구나이 모든 것을 모두 달성 할 수있는 다른 방법이 있습니까? 간과 할 수없는 무언가가있는 것 같은 느낌.
미리 감사드립니다.
AHHA을! 나는 이것이 어떻게 작동하는지 보았다 - 고마워! 'Boolean'을 추가하는 것이 쉽고, Numer'의 LUB은'Complex'를 위해 너무 쉽게 변경되지 않습니다. 궁금한 점이 있습니다.이 솔루션을 슬리브에 넣은 것 같은데, 어떤 상황에서이 문제를 겪었습니까? 또한이 솔루션의 성능을 테스트하고 백만개의'C [Int] '가 백만 분의'Int's보다 약 5 배 느린 것으로 보입니다. 시작하는 방법에 대한 생각 이것을 최적화할까요? – ostolop
IRC에서 @extempore와 토론하는 동안이 문제를 해결했지만 문제가 해결되지 않았습니다. 간접비를 고려할 때 5 배의 오버 헤드가 나쁘지는 않습니다. 'unify' 메소드를 사용하는 대신'wc.a2b'와'wc.a2c'를 직접 호출 할 수 있습니다. 현재 'NumeriC# plus'의 입력과 출력은 박스로되어 있습니다. 앞으로의 스칼라 버전에서는 그 문제를 @specialize 할 수있는 방법을 찾을 수있을 것입니다. – retronym
@retronym 사실 ... 나는 그 토론을 시작했다. :-) –