2013-10-23 3 views
1

유형 매크로가 꺼져 있습니다.유형 매크로가 작동하지 않습니다. 어떻게 정의에서 유형을 계산할 수 있습니까?

그러나 중요한 두 가지 사례가 필요합니다. 결과적으로 응용 프로그램에서 중요한 확장 성을 잃을 수 있습니다. 둘 다 다른 유형이 주어진 유형의 동적 컴파일 시간 생성입니다. 기본적으로 내가 좋아하는 것을하고 싶어 (분명하지 스칼라 코드를하지만 난 당신이 아이디어를 얻을 수있을 거라 생각) :

type T[U] = macro usecase1[U] 

def usecase1[U]= U match { 
    case t if (t <:< Int) => String 
    case ... => ... 
} 

두 번째 사용 사례는 다음과 같습니다

type Remaining[A, B >: A] = macro ... 

경우 예를

에 대한
class C 
trait T1 extends C 
trait T2 extends C 

type Remaining[C with T1 with T2, T2] is assigned to "C with T1" at compile time 
(so the macro would have generated the subclass list, and generated a new type from the list without T2) 

매크로를 사용하지 않았으므로 가정합니다. 나는 그 타입 매크로가 죽을 때까지 지금 그것을 할 계획이었다. 어쨌든, 그런 기능을 얻기위한 트릭을 아는 사람이 있습니까? 감사합니다.

+0

첫 번째 예에서는 _usecase_가 아닌 매크로 정의가 표시됩니다. 실제 사용 사례가 없으면 (여기서'T [U]'가 필요합니다) 평가하기가 어렵습니다. 그러나 여기서는 매크로가 필요하지 않지만 상자에서 작동 할 수있는 몇 가지 유형 제한이 있습니다. –

+1

스칼라 유형은 매우 유연합니다. 고급 유형의 사용법에 대해서는 scalaz와 shapeless (https://github.com/milessabin/shapeless)를 참조하십시오. –

+0

@ 0__ 두 번째 사용 사례는 [link] (http://jim-mcbeath.blogspot.fr/2009/09/type-safe-builder-in-scala-part-4.html)와 같은 것을 수행하는 것입니다. 그러나 복잡한 옵션, 예 : "옵션 A를 연결하면 B를 플러그 할 수 없으며 D는 C 등을 연결 한 후에 플러그를 꽂을 수 있습니다." 나는 링크와 같은 것으로 끝났지 만, 패턴 케이스를 가진 짧은 readeable 코드를 갖는 대신에, 나는 자식 클래스들에 걸쳐 모든 트리를 철저히 씁니다. 첫 번째 사용 사례는 자동 변환입니다. 다시 간단한 알고리즘으로 처리 할 수 ​​있지만 모든 클래스를 다른 클래스로 작성해야합니다. –

답변

1

첫 번째 유스 케이스는 실제로 이해할 수있을 정도로 어느 정도 implicits로 구현할 수 있습니다. 다음

scala> trait Bound[A] { 
    | type Type 
    | } 
defined trait Bound 

scala> implicit val bound1 = new Bound[Int] { type Type = String } 
bound1: Bound[Int]{type Type = String} 

scala> implicit val bound2 = new Bound[String] { type Type = Double } 
bound2: Bound[String]{type Type = Double} 

scala> val tpe = implicitly[Bound[Int]] 
tpe: Bound[Int] = [email protected] 

scala> type U = tpe.Type 
defined type alias U 

:하지만

scala> implicitly[bound1.Type =:= String] 
res0: =:=[bound1.Type,String] = <function1> 

암시 해상도가 길에 일부 유형을 잃고있는 것 같다 : 한편

scala> implicitly[U =:= String] 
<console>:19: error: Cannot prove that U =:= String. 
       implicitly[U =:= String] 
         ^

여기에이 같이하는 방법의 예 . 이유와 그 문제를 해결하는 방법을 모릅니다. 두 번째 사용 사례를 들어


, HList 즉시 떠오른다들. 같은 뭔가 :

scala> trait Remaining[A <: HList, B] { type Result = Remove[A, B] } 
defined trait Remaining 

scala> new Remaining[C :: T1 :: T2 :: HNil, T2] {} 
res5: Remaining[shapeless.::[C,shapeless.::[T1,shapeless.::[T2,shapeless.HNil]]],T2] = [email protected] 

하지만 복합 형으로 결과 HList을 결합하는 방법을 잘하지 않습니다. 뭔가 (의사 코드) :

trait Remaining[A <: HList, B] { 
    def produceType(
    implicit ev0 : Remove.Aux[A, B, C], 
      ev1 : IsCons.Aux[C, H, T], 
      ev2 : LeftFolder[T, H, (T1, T2) => T1 with T2]) = ev2 
      //     ^Not real syntax, type-level function to combine/mix types 
    val tpe = produceType 
    type Result = tpe.Out 
} 
+0

감사합니다. scala 컴파일러에 대한 액세스 권한이 없지만 'type U = tpe.type # Type' 정보를 잃어 버리지 않을 것 같습니다. –

관련 문제