2013-01-13 2 views
5

일반적으로 IOArray 또는 MArray 중에서 슬라이스 (하위 배열보기)를 효율적으로 구성하는 방법이 있습니까? 즉, 동일한 배열을 사용하여 경계를 제한하는 것입니다. 서명은 경계 (1,1000) 배열을 취하고 만 경계 일본어 배열 (500,700)와 소자에 대한 액세스를 제공하는 도면을 예를 들어IOArray (또는 일반적으로 MArray) 썰기

(MArray a e m, Ix i) => a i e -> i -> i -> m (a i e) 

수 있었다. 문서를 검색했지만 그런 기능을 찾을 수 없습니다.

+0

그래서'[500..700]'_remapped_에서'[0..200]'까지의 범위를 갖기를 원하거나 어떤 방식 으로든 접근 할 수 있어야합니다 (예를 들어, 외부에서 접근 할 때'IO' 예외를 던지면됩니다. 범위)? '[(20,20) .. (40,40)]'과 같은 범위를 가진 다차원 배열의 경우 어떻게 동작할까요? – leftaroundabout

+4

그렇게 생각하지 않지만 Data.Vector http://hackage.haskell.org/package/vector-0.10.0.1을 사용하면 조각을 추출 할 수 있습니다. 융합 최적화 규칙도 있으므로 일반적으로보다 효율적입니다. –

+0

@leftaroundabout 다시 매핑 할 필요가 없습니다. 기본적으로 내가 원하는 것은'getBounds'가 제한된 범위를보고하는 동일한 배열을 갖는 것입니다 (그리고 아마도 외부 요소에 액세스하면 예외가 발생하지만 이것은 필요하지 않습니다). –

답변

5

배열 유형이 구현되는 방식을 감안할 때 실제로 배열의 기능이 될 수있는 것은 아닙니다.이 배열은 이미 존재하지 않습니다.

배열은 인접한 메모리 블록이므로 어떤 레벨에서는 n 요소를 가진 모든 배열이 (0, n-1) 범위를 갖습니다. 그러나 Haskell은 임의의 경계를 정의하고 그 경계 내부의 요소에서 실제 메모리 블록에 대한 0 기반의 정수 인덱스로 변환하기 위해 Haskell이 제공하는 정수 이외의 인덱스를 원한다.

배열의 경계가 전체 범위를 차지한다고 가정하기 때문에 이렇게하기가 어려울 수 있습니다. 따라서 동일한 메모리 덩어리를 사용하지만 다른 경계를 사용하는 기존 배열의 복사본을 만드는 경우 인덱스가 정렬되지 않습니다. 예에서 하위 배열의 인덱스 500은 원본의 인덱스 1과 같을 것입니다 정렬. 도움이되지 않습니다.

가장 간단한 방법은 기존 배열을 래핑하고 인덱스를 변환하는 데 필요한 추가 정보를 저장하는 자체 배열 유형을 정의하여 해당 범위를 더 작은 범위로보고하지만 래핑 된 내용을 찾습니다. 배열 전체 범위를 기반으로합니다. 그런 다음 래핑 된 배열 유형을 모든 곳에서 사용할 수 있으며 "실제"배열과 동일한 경계를 사용하여 새로 만든 배열을 사용하여 모든 예상 인스턴스 (&.c.)를 제공 할 수 있습니다. 여기에있는 색인에서 필요한 번역을 수행 할 수 있으므로이 방법은 선형 순서가없는 색인 유형 (예 : 튜플로 색인화 된 '다차원'배열)으로 일반화해야합니다.

인덱스 유형을 감싸는 래퍼와 관련된 작업을 수행하고 래퍼 버전에 이상한 Ix 인스턴스를 부여하여 기존의 배열 유형을 사용할 수 있도록 할 수 있습니다. 그래도 제대로 작동하게하려면 다소 까다로울 수 있습니다.

배열이나 인덱스 유형을 변경하지 않고는 아무 것도 할 수 없다고 생각합니다.