잘 정의 된 관계를 지닌 속성을 가진 특성을 정의하고 싶습니다. 예를 들어, a * b = c
이라고 가정 해 봅시다. 아이디어는이 특성의 구현이 두 가지를 제공하고 자동으로 파생 된 세 번째 속성에 대한 접근자를 가질 수 있다는 것입니다. 당신이 나머지로 너무 오래 기능의 부분 집합을 정의 할 수 있지만 -스칼라에서 상호 의존적 인 기본 메소드 구현을 추론하기
(이 하스켈의 타입 클래스와 같은 기능은 내가 정확히, 당신은 (I 제대로 하스켈의 타입 클래스를 기억하지 않는다)Ord
에서 <
을 정의 된 경우 어디 사람들을 기억한다면, >=
가 ! . <
로 구현 될 수있다 . 추론 할 수있다)
초보적인 방법은 실제로 꽤 잘 작동합니다.
여기trait Foo {
// a * b = c
def a: Double = c/b
def b: Double = c/a
def c: Double = a * b
}
class FooOne(override val a: Double, override val b: Double) extends Foo
class FooTwo(override val a: Double, override val c: Double) extends Foo
, 구현를및 FooTwo
은 Foo
의 완전한 구현이며 예상대로 작동합니다. 여태까지는 그런대로 잘됐다; 이 접근 방식은 클래스가 두 개의 속성을 정의하고 세 번째 속성을 "무료"로 가져올 수있게합니다.
그러나, 물건 하나 제 3 클래스를 정의하는 경우 덜 장미 빛보고 시작합니다
는class FooFail(override val a: Double) extends Foo
이 잘 컴파일 - 그 b
또는 c
방법이 지금까지 평가하는 경우 그러나, 그것은 스택 오버 플로우가 발생합니다.
그래서 순진한 접근 방법은 하스켈의 타입 클래스 방식의 추론 측면을 제공하지만, 우리는 컴파일시 안전성이 없습니다. 클래스의 구현에 의해 두 개 미만의 메소드가 정의되는 경우 컴파일러가 불평 할 것입니다. 분명히 현재 구문만으로는 충분하지 않습니다. 의존적 인 메소드가 추상적이지 않은 경우에만 사용될 수있는 기본 구현이긴하지만, 추상화 된 메소드를 필요로합니다.
Scala는 이것을 정의하기 위해 적절한 의미를 폭로합니까? (이 언어에 대한 어떤 일류 지원도 알지 못하기 때문에 union types과 비슷한 다소 둥근 방법을 정의하면 문제가 없습니다.)
그렇지 않다면, 나는 순진한 접근법을 사용하고 수업을 신중하게 정의하고 테스트 할 것입니다. 그러나 저는 이것이 타입 시스템이 잡을 수 있어야한다고 생각합니다 (결국 루비가 아닙니다. :)).
완전히 잊어 버리지 않는 한 하스켈은 똑같은 문제에 대해 똑같은 순진한 접근법을 사용합니다. –
@Alexey - 흥미로운 의견입니다. 그것은 오래되었지만 당신이 메서드를 충분히 정의하지 않으면 컴파일러/인터프리터 오류가 발생하여 형식 클래스의 모든 메서드를 파생시킬 수 없다는 것을 상기하는 것 같습니다. 어쩌면 이것을 재현 해 보도록하겠습니다. 하스켈이 영감을 얻으려는 방법에 대해 읽어 봅니다. –
OK, 하스켈에서 이것을 테스트 한 결과 실제로 똑같은 문제가 발생했습니다 (완전히 추상적 인 메소드에 대해서만 경고한다는 점에서 스칼라 상황과 동일합니다). 즉, 다른 언어로 선례가 없더라도 여전히 의문이 남아 있습니다. –