2016-08-17 6 views
3

의 내가 여러 유형의 매개 변수를 취하는 데프이 있다고 가정하자스칼라에서 def의 "curry"유형 매개 변수를 사용할 수 있습니까?

def foo[A, B, C](b: B, c: C)(implicit ev: Writer[A])

그러나, 사용 목적은 BC 추론해야하는 유형 매개 변수입니다 (전달 된 인수 기준). 호출자는 실제로 A을 명시 적으로 지정해야합니다 (예 : 컴파일러에서 적절한 암시 적으로 선택하도록). 불행히도 스칼라에서는 호출자가 형식 매개 변수를 모두 지정하거나 지정하지 않을 수 있습니다. 어떤 의미에서, 나는 형 매개 변수 카레 싶은 : 스칼라에서이 작업을 수행하는 몇 가지 트릭

def foo[A][B, C]...

있습니까?

(내 구체적인 예 내가 제안을 개선하기 위해 행복 해요 완전한 이해가되지 않는 경우.)

답변

5

내가 이것을 해낼 수있었습니다 가장 좋은 방법은 보유하는 클래스를 정의하는 것입니다 curried 형식 정보는 apply 메서드를 사용하여 함수 호출을 시뮬레이트합니다.

내가 여기에 대해 서면으로 작성했습니다 - 특정 예를 들어 http://caryrobbins.com/dev/scala-type-curry/

, 당신은 foo을위한 서명에 apply하지에 대한 서명에 implicit ev: Writes[A]을 둘 필요가 것입니다. 명시 적으로 암시 적 인수를 전달하거나 암시 적으로 apply 메서드를 호출하는 경우 모호성이 발생하기 때문입니다.

object Example { 
    def foo[A]: _Foo[A] = _foo.asInstanceOf[_Foo[A]] 

    final class _Foo[A] private[Example] { 
    def apply[B, C](b: B, c: C)(implicit ev: Writes[A]): Unit = ??? 
    } 

    private lazy val _foo = new _Foo[Nothing] 
} 

당신은 다음 카레하고자하고 apply 메서드에 전달 된 다음 인수를 추론 할 것이다 형식 매개 변수를 제공 할 수 있습니다 -

은 여기 예를 들어 예를 구현합니다. 당신은 다른 유형의 매개 변수를 지정할 필요가 끝날 경우

Example.foo[Int]("bar", new Object) 

, 당신은 명시 적으로 apply를 호출하여 수행 할 수 있습니다; 아직, 나는 이것을 아직 할 필요가 없다는 것을 알았다.

Example.foo[Int].apply[String, Object]("bar", new Object) 

당신이 또한 내가 상기 포스트에서 논의 구조 유형을 사용할 수있는 중간 형식을 사용하지 않으려면, 그러나이 경우 reflectiveCalls과 유추 된 형식 서명이 필요합니다. 둘 다 피하기를 좋아합니다.

+1

매우 잘 작성되었으며 매우 영리합니다. – Alec