Development Tip

스칼라의 튜플 구문이 왜 그렇게 특이한가요?

yourdevel 2020. 11. 3. 19:19
반응형

스칼라의 튜플 구문이 왜 그렇게 특이한가요?


수학 및 컴퓨터 과학에서 튜플은 정렬 된 요소 목록입니다. 집합 이론에서 (정렬 된) n- 튜플은 n 요소의 시퀀스 (또는 정렬 된 목록)이며, 여기서 n은 양의 정수입니다.

예를 들어, 파이썬에서 튜플의 두 번째 항목은 t[1].

Scala에서 접근은 이상한 이름을 통해서만 가능합니다 t._2.

그래서 질문은 왜 정의에 의해 튜플의 데이터에 Sequence 또는 List로 액세스 할 수 없습니까? 어떤 종류의 아이디어가 있습니까 아니면 아직 검토되지 않았습니까?


스칼라는 튜플의 인수에 대응을 알고 있으며, 따라서 같은 접근 제공 할 수 있습니다 _1, _2등, 당신이 선택하면 컴파일 타임 오류가 발생 _3예를 들어, 한 쌍. 또한 이러한 필드의 유형은 매개 변수로 사용 된 유형과 정확히 일치합니다 Tuple(예 : _3a Tuple3[Int, Double, Float]a 를 반환합니다 Float).

n 번째 요소에 액세스하려면을 작성할 수 tuple.productElement(n)있지만이 반환 유형은 여야 만 가능 Any하므로 유형 정보를 잃게됩니다.


"스칼라 프로그래밍 : 포괄적 인 단계별 가이드"(Martin Odersky, Lex Spoon 및 Bill Venners)에서 발췌 한 다음 발췌문이 두 가지 질문을 직접적으로 다룹니다.

튜플의 요소에 접근하기

예를 들어 "pair (0)"과 같이 목록의 요소와 같은 튜플의 요소에 액세스 할 수없는 이유가 궁금 할 수 있습니다. 그 이유는 목록의 apply 메소드가 항상 동일한 유형을 반환하지만 튜플의 각 요소는 다른 유형일 수 있기 때문입니다. _1은 하나의 결과 유형을 가질 수 있고 _2 다른 유형을 가질 수 있습니다. 이 _N 숫자는 0부터 시작하는 대신 1부터 시작합니다. 1로 시작하는 것은 Haskell 및 ML과 같은 정적으로 형식화 된 튜플이있는 다른 언어에서 설정 한 전통이기 때문입니다.

Scala 튜플 '(' a1, ..., an ')'은 컴파일러에서 scala.Tuplen ( a1, ..., an ) 클래스 인스턴스화 의 별칭으로 처리되는 표현식을 제외하고 언어 구문에 관한 한 우대적인 취급을 거의받지 않습니다 . 그렇지 않으면 튜플은 다른 Scala 객체처럼 동작합니다. 사실 Tuple2에서 Tuple22 범위의 케이스 클래스 로 Scala에서 작성됩니다 . Tuple2 및 Tuple3은 각각 Pair 및 Triple 별칭으로도 알려져 있습니다.

 val a = Pair   (1,"two")      // same as Tuple2 (1,"two") or (1,"two") 
 val b = Triple (1,"two",3.0)  // same as Tuple3 (1,"two",3.0) or (1,"two",3.0)

List, Seq또는 컬렉션과 튜플의 한 가지 큰 차이점은 튜플에서 각 요소가 자체 유형을 가지며 List에서 모든 요소가 동일한 유형을 갖는다는 것입니다.

그리고 결과로, 스칼라에서는 같은 클래스를 찾을 수 Tuple2[T1, T2]또는 Tuple3[T1, T2, T3]각각의 요소에 대한 당신은 또한 유형의 매개 변수가 있습니다. 컬렉션은 하나의 유형 매개 변수 만 허용합니다 List[T].. 같은 구문 ("Test", 123, new Date)Tuple3[String, Int, Date]. 그리고 _1, _2등은 해당 요소를 반환하는 튜플의 필드 일뿐입니다.


형태없는 상태로 쉽게 얻을 수 있습니다 .

import shapeless.syntax.std.tuple._

val t = ("a", 2, true, 0.0)

val s = t(0) // String at compile time
val i = t(1) // Int at compile time
// etc

표준 집합 가능한 많은 방법은 튜플이 가능한 방법 ( head, tail, init, last, ++:::연결 용, +::+요소를 추가, take, drop, reverse, zip, unzip, length, toList, toArray, to[Collection], ...)


일반적인 인덱스 액세스를 사용하면 모든 표현식을 사용할 수 있으며 인덱스 표현식의 결과가 범위 내에 있는지 확인하려면 컴파일 타임에 확인하는 데 심각한 노력이 필요합니다. 속성을 만들고 (1, 2)._3"무료"에 대한 컴파일 타임 오류를 만듭니다. 튜플에 대한 항목 액세스 내에서 정수 상수 만 허용하는 것과 같은 것은 매우 특별한 경우 (추악하고 불필요하며 일부는 우스꽝 스럽다고 말할 수 있음)이며 컴파일러에서 구현할 작업도 있습니다.

예를 들어 파이썬은 인덱스가 범위 내에 있는지 확인 (컴파일 타임에)하지 않을 것이기 때문에 (컴파일 할 수 없기 때문에) 벗어날 수 있습니다.


유형 검사 용이라고 생각합니다. delnan이 말했듯이 튜플 t과 인덱스 e(임의의 표현식)가 있으면 t(e)컴파일러에 액세스중인 요소에 대한 정보를 제공하지 않습니다 (또는 해당 크기의 튜플에 유효한 요소 인 경우에도). 필드 이름 ( _2유효한 식별자, 특수 구문이 아님)으로 요소에 액세스 할 때 컴파일러는 액세스중인 필드와 해당 유형을 알고 있습니다. Python과 같은 언어에는 실제로 유형이 없기 때문에 필요하지 않습니다.


Jean-Philippe Pellet이 이미 언급 한 이점 외에도이 표기법은 수학에서도 매우 일반적입니다 ( http://en.wikipedia.org/wiki/Tuple 참조 ). 많은 강사가 튜플의 요소를 참조하려는 경우 튜플 변수에 인덱스를 추가합니다. "with index n "( 튜플 n 번째 요소 참조 )을 작성하는 일반적인 (LaTeX) 표기법 은 다음과 같습니다 _n. 그래서 저는 그것이 실제로 매우 직관적이라고 생각합니다.

참고 URL : https://stackoverflow.com/questions/6884298/why-is-scalas-syntax-for-tuples-so-unusual

반응형