2017-09-24 3 views
3

왜 배열과 문자열 색인은 미묘하게 다른 구문을 사용합니까?문자열 대 배열 색인에 대한 구문

예.

let _: int = [|1;2;3|].(0) 
let _: char = "123".[0] 

I (및 기타)는 이것이 이상하고 혼란 스럽다고 생각합니다. OCaml의 플로트 추가에 대한 정수 추가에 대한 ++.를 사용하는 것이 정확히 같은 이유로

답변

5

는 : OCaml로는 임시 다형성/함수 오버로드 및 인덱싱 사업자가 현재 OCaml의 함수의 한 형태로 간주되므로 적용을 받는다 포기합니다 기능과 동일한 제한 사항.

더 정확하게, 인덱싱 사업자들은 현재 매우 얕은 구문 설탕 있습니다 : 파서는 x.(n)Array.set x n y-Array.get x n에와 x.(n) <- y 다시 작성 (또는 Array.unsafe_getArray.unsafe_set-unsafe 옵션을 사용하여 컴파일 된 경우). 유사하게, s.[n]String.get s n으로 다시 쓰여지고 s.[n]<-xString.set s n x이됩니다.

즉, 새 Array 모듈을 정의하여 사용자 고유의 인덱싱 연산자를 정의 할 수 있습니다. hackish 이런 종류의 코드가 미래에 작동한다는 보장은 없습니다

module Array = struct 
    include Array 
    let get a n = get a (n-1) 
    let unsafe_get a n 
end 
;; [|1|].(1) 

하는 것으로 : 예를 들어, 다음과 같은 경솔한 트릭은 배열 인덱스가 1에서 시작하게됩니다. 자신 만의 인덱싱 연산자를 정의하고자한다면 OCaml ≥ 4.06부터 시작하여 도트 .과 왼쪽 대괄호 ((, [, {) 사이에 최소 하나의 (연산자) 문자를 삽입하여 확장 된 인덱스 연산자를 정의 할 수 있습니다.

let (.?()) dict key = Dict.find_opt dict key 

당신은 어떻게 든 덜 색인 사업자 소원, 배열과 같은 데이터 유형에 대한 색인 원시적 작동하지 함수 호출을 만들 수있는 제안이 있다면. 이렇게하면 레코드 필드에 대해 이미 완료된 것처럼 유형 지정 불일치 제거를 사용할 수 있습니다. 이는 타입 검사기가 어떤 원시 연산이 사용되어야 하는지를 결정하기 위해 타입 정보를 사용할 것이므로

let first (s:string) = s.(0) 
let first (a: _ array) = a.(0) 

이 가능하다는 것을 의미합니다.

그러나이 제안은 여전히 ​​진행 중이며 (https://github.com/ocaml/ocaml/pull/616 참조), 지금은 구문에 따라 문자열 배열과 일반 배열 색인을 구별해야합니다.

관련 문제