스칼라의 튜플 구문이 왜 그렇게 특이한가요?
수학 및 컴퓨터 과학에서 튜플은 정렬 된 요소 목록입니다. 집합 이론에서 (정렬 된) n- 튜플은 n 요소의 시퀀스 (또는 정렬 된 목록)이며, 여기서 n은 양의 정수입니다.
예를 들어, 파이썬에서 튜플의 두 번째 항목은 t[1]
.
Scala에서 접근은 이상한 이름을 통해서만 가능합니다 t._2
.
그래서 질문은 왜 정의에 의해 튜플의 데이터에 Sequence 또는 List로 액세스 할 수 없습니까? 어떤 종류의 아이디어가 있습니까 아니면 아직 검토되지 않았습니까?
스칼라는 튜플의 인수에 대응을 알고 있으며, 따라서 같은 접근 제공 할 수 있습니다 _1
, _2
등, 당신이 선택하면 컴파일 타임 오류가 발생 _3
예를 들어, 한 쌍. 또한 이러한 필드의 유형은 매개 변수로 사용 된 유형과 정확히 일치합니다 Tuple
(예 : _3
a 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
'Development Tip' 카테고리의 다른 글
Rails 마이그레이션 : 존재 여부를 확인하고 계속 진행 하시겠습니까? (0) | 2020.11.03 |
---|---|
MySQL에 IP 주소를 저장하는 가장 효율적인 방법 (0) | 2020.11.03 |
m2eclipse 오류 (0) | 2020.11.03 |
투명한 CSS 배경색 (0) | 2020.11.03 |
angularjs는 텍스트 상자에서 대문자를 강제합니다. (0) | 2020.11.02 |