2011-08-23 7 views
4

값으로 매개 변수화 된 형식을 스칼라에서 만들 수 있습니까? 부분 형식 List[A]을 정의하고 List[Int]으로 매개 변수화하는 대신 부분 형식 (의사 코드로) Element[Symbol]을 정의하고 Element['td]으로 매개 변수를 정의하고 싶습니다. 이 예에서이 유형은 XML 요소를 나타냅니다. Element['td]은 스칼라 유형 검사기에 <td> 요소가 있음을 알리고, <td> 요소를 특별히 기대하거나 반환하는 API가 있다고 상상할 수 있습니다.스칼라 : 형식 대신 값으로 매개 변수화 된 형식을 만드는 방법

(서브 클래스, 그 다음 다른 것으로 간주됩니다 코드의 두 조각, 어쩌면 <td>에 대한 선언 다른 서브 클래스에서, 독립 개발자에 의해 작성을 방지하지 않는 한, 매우 만족스러운 해결책은 아니다 class Td extends Element 같이 타입).

+0

나는 그것이 가능하지 않다고 생각합니다. –

+0

아마도 많은 내부 클래스와 경로 종속 유형을 사용하고 있을까요? – soc

답변

4

형식으로 값을 매개 변수화하려는 경우 Agda와 같은 종속 형식의 프로그래밍 언어가 필요합니다.

+0

스칼라 _ 의존적으로 타입이 지정된 프로그래밍 언어입니다. 싱글 톤 유형이 아니더라도 충분히 가까이 다가 갈 수 있습니다. 값을 유형으로 옮길 수 있기 때문에 값에 해당하는 유형을 값의 해당하는 유형에 따라 유형으로 인코딩 할 수 있습니다. –

+0

@Miles Sabin : 기술적으로 사실 일지 모르지만, 예를 들어 길이에 대해 Int 매개 변수가있는 목록 유형을 어떻게 만들지는 모르겠다. 어떤 아이디어? –

+0

Ints 용 싱글 톤 유형은 스칼라 유형 검사기에 내부적으로 있지만 현재 구문이 없습니다 (패치 및 토론은 http://existentialtype.net/2008/07/21/literally-dependent-types/ 참조) . 그러나 모든 참조 유형에 대해 이것은 전적으로 가능합니다 ... 내 대답은 아래 참조하십시오. –

1

당신이 정말로 원하는 것은 (C++에서와 같이) 값으로 타입을 매개 변수화하는 것이 아니라 다양한 개발자가 공통 구현에 동의하도록하는 것입니다.

나는 언어가 당신을 위해 해결할 것이라고 생각하지 않습니다. <td> 유형을 사용하는 한 가지 방법 만 강요하더라도 정확히 <td> 유형에 어떤 재량이 아직없는 것입니까?

object TD { 
} 

즉 이제 Element[TD]을 쓸 수 있습니다, 그것은 실제로 유형이 될 수 있도록 당신이 정말로 값으로 유형을 매개 변수화 할 경우

, 당신은 아마 뭔가를해야 할 것이다. 그래도 다른 사람이 object TD { }을 다른 패키지에 쓸 수 있다는 문제가 있지만 그 중 두 개가있을 것입니다.)

당신이 시도하고 "TD는"

TyString[T,TyString[D,()]] 

로 표현 될 것이다 그러나 당신은 아마 거기에 가고 싶지 않아 그래서

object A { } 
object B { } 
object C { } 
... 

object TyString[Car,Cdr] { } 

같은 것을 사용하여 전체 의존 유형을 에뮬레이트 할 수

(나는 스칼라가 "싱글 톤 리터럴"이라고 불리는 것을 구현할 것이라고 들었다. 그러나 그런 일이 일어 났는가? "td".type을 쓸 수 있어야한다. 스칼라 2.9.1은 그 문법을 받아들이지 않는다).

+0

마지막 코멘트에 대해 다음 작품이 나에게 도움이된다 :'val x = "string"; null : x.type'. 그러나'x'가'val' 대신에'var'로 선언되면 컴파일러는'x'가 안정적인 식별자가 아니라는 에러를냅니다. –

+0

매우 흥미 롭습니다. 싱글 톤 유형을 사용할 수있는 방법을 볼 수 있습니다. 그러나 나는 의아해한다. 나는'val s = 's; val x : s.type = s' 왜'val s = 's를 쓸 수 없습니까; val x : s.type = 's' (유형 불일치로 연결됨, found : Symbol, required : s.type)? – avernet

2

그냥 놀아야 할 몇 가지 아이디어 ... 개체는 값이고 유형이 있습니다.

trait XmlElement 
object Td extends XmlElement 

그런 다음 매개 변수가있는 클래스를 사용하여 특정 유형에 사용할 수 있습니다.

class Element[T <: XmlElement] { ... } 
val elementOnTd = new Element[Td.type] 
// elementOnTd can only be used with Td. 

이 당신이 밀봉 특성을 만들 수 있습니다 당신은 다음 지원하려는 요소의 고정 된 숫자가 아니라 당신의 라이브러리는

sealed trait XmlElement 
object Td extends XmlElement 
object Tr extends XmlElement 
// can't have anything other than `Td` and `Tr` ! 

(즉 보이지만 꽤 제한) 이러한 개체와 함께 작동됩니다 당신이 할 수있는 또 다른 일은 객체의 내부 클래스가 같은 타입을 가지고 있지 않다는 것입니다. 따라서 라인 object Td { class Element { ... } }Td.Element을 따라 수행 할 작업은 Tr.Element과 동일한 유형이 아닙니다.

1

싱글 타입은 당신이 이미 표현하는 유형 (밀봉) 가족을 만들어 있었다 수없는 아무것도 포기하지 않을거야,하지만 당신은 당신이 요구하고 원하는

scala> class Element[+T] 
defined class Element 

scala> val td = 'td 
td: Symbol = 'td 

scala> val p = 'p 
p: Symbol = 'p 

scala> def acceptAll[T](e : Element[T]) = e 
acceptAll: [T](e: Element[T])Element[T] 

scala> def acceptTd(e : Element[td.type]) = e 
acceptTd: (e: Element[td.type])Element[td.type] 

scala> acceptAll(new Element[p.type])  // OK 
res3: Element[Symbol] = [email protected] 

scala> acceptAll(new Element[td.type])  // OK 
res4: Element[Symbol] = [email protected] 

scala> acceptTd(new Element[td.type])  // OK 
res2: Element[td.type] = [email protected] 

scala> acceptTd(new Element[p.type])  // Doesn't compile 
<console>:12: error: type mismatch; 
found : Element[p.type] 
required: Element[td.type] 
       acceptTd(new Element[p.type]) 
        ^

을 줄 것이다 요소 이름. 여기서 Scala Symbol을 사용하는 것에 특별한 것은 없음에 유의하십시오. 참조 유형의 안정적인 식별자는 동일한 방식으로 사용될 수있는 고유 한 싱글 톤 유형을 발생시킵니다.

관련 문제