2012-02-11 7 views
1

내 프로그램을 Data.Array에서 Data.Array.Unboxed로 변환하려고합니다. 빠른 보조 노트로 하스켈 어레이에서 박스 안의 배열로 변환하면 다시 쓰기 규칙이 깨집니다.

: 여러 장소 내가 그러나 내가 배열의 두 유형을 혼합하고 있지 않다, 내 코드 에서 "UArray"에 "배열"로 변경하고 Data.Array.Unboxed의 수입을 추가 할 수있는 상태 그래서 방금 ​​Data.Array 대신 Data.Array.Unboxed를 가져 왔습니다.이 정도면 충분합니까?

I 스위치 다음 다시 쓰기 규칙 휴식 할 때 :

{-# RULES 
    "applyWindow/applyWindow" forall win1 win2 image. 
            applyWindow win1 
               (applyWindow win2 
               image) = 
            applyWindow (indexMult win1 win2) 
                  image 
    #-} 
다음

win1 WIN2 및 이미지를 모두해야 UArrays. 그러나이 오류로 인해 컴파일되지 않습니다.

FIPlib/Core.hs:229:99: 
    Ambiguous type variables `e0', `a0' in the constraint: 
     (IArray a0 e0) arising from a use of `applyWindow' 
    Probable fix: add a type signature that fixes these type variable(s) 
    In the expression: applyWindow (indexMult win1 win2) image 
    When checking the transformation rule "applyWindow/applyWindow" 

FIPlib/Core.hs:229:99: 
    Ambiguous type variables `e0', `a2' in the constraint: 
     (IArray a2 e0) arising from a use of `applyWindow' 
    Probable fix: add a type signature that fixes these type variable(s) 
    In the expression: applyWindow (indexMult win1 win2) image 
    When checking the transformation rule "applyWindow/applyWindow" 

FIPlib/Core.hs:229:112: 
    Ambiguous type variables `e0', `a1' in the constraint: 
     (IArray a1 e0) arising from a use of `indexMult' 
    Probable fix: add a type signature that fixes these type variable(s) 
    In the first argument of `applyWindow', namely 
     `(indexMult win1 win2)' 
    In the expression: applyWindow (indexMult win1 win2) image 
    When checking the transformation rule "applyWindow/applyWindow" 

무엇이 모호한가? 왜 Data.Array와 함께 작동합니까?

답변

3

문제 Data.Array.Unboxed 재수출 Data.Array.IArray 및 불변 어레이 인터페이스 따라서 IArray 클래스 Data.Array하지만 (이것은 심지어 가져 오지 않음)하지 않는다는 것이다. 따라서 bounds, accumArray, array 등의 코드를 가져온 경우 Data.Array 만 가져올 경우 배열 형식이 단일형이므로 모호성이 발생하지 않습니다 (요소 유형의 다형성이 문제를 일으키지 않는 것으로 보입니다. 타입 클래스 제약). 그러나 Data.Array.Unboxed을 가져 오는 경우이 모든 함수는 IArray a e 제약 조건을 가지므로 다시 쓰기에 다른 배열 유형이 포함되어 중단 될 수 있습니다. 형식 시그니처, 함수 또는 규칙을 사용하여 유형을 수정해야합니다. 이 문제를 정확히 해결하려면 코드를 보지 않고 말할 수 없습니다.

참고 : 유형 검사가 7.4로 변경되었으며 ghc-7.4.1을 사용하면 Data.Array.Unboxed을 가져 오는 경우 규칙이없는 코드가 유형 서명없이 컴파일되지 않습니다. 규칙이 모호함으로 실행되지 않도록

이 유형을 해결하려면, 당신은 두 지역의 바인딩에 유형 서명을 applyWindow에 최상위에

  • ,
  • 을 제공해야 paddedImagefilteredPaddedImage.

모든 관련 배열이 동일한 유형을 가지고하는 요소 유형도 Word이 될 수있다 (즉

  1. monmorphic 유형, 말 UArray (Int,Int) Int 될 수 있습니다 아마 원하는 가장 합리적인 ...)
  2. 요소 유형의 형 배열 유형 단형과 다형성
  3. T이 어디 1. 모두

의 유형 ploymorphic는 단순히 서명, applyWindow :: T -> T -> TxxImage :: T을 (추가해야 원하는 유형). 2.를 들어, 두 개의 언어 확장, FlexibleContextsScopedTypeVariables를 추가해야 다음 applyWindow는 서명 xxImage :: UArray (Int,Int) e을 얻을 것 서명

applyWindow :: forall e. (Num e, IArray UArray e) 
      => UArray (Int,Int) e -> UArray (Int,Int) e -> UArray (Int,Int) e 

로컬 바인딩을 얻을 것입니다. FlexibleContexts은 constarint에서 UArray의 발생을 허용해야하며 paddedImagefilteredPaddedImage이 형식 시그니처를 전혀 얻을 수 있도록 요소 유형을 범위로 가져 오려면 ScopedTypeVariables이 필요합니다. 3.를 들어, 단지 ScopedTypeVariables 필요하다 applyWindow의 유형 서명이 다음 (로컬되지 않는 바인딩)를 사용하여 asTypeOf 또는 목록에 그들 모두를 가하고

applyWindow :: forall a e. (Num e, IArray a e) => ... 

또 다른 방법은 동일한 유형의 모든 배열을 강제하는 것입니다, 그러나 IMO 유형 서명이 바람직합니다.

일단 모든 유형이 고정되면 (반드시 동일 할 필요는 없지만 로컬 바인딩의 유형은 인수 유형과 결과 유형, 경우에 따라 인수 유형으로 결정되어야 함) 규칙에 check를 입력해야합니다. (indexMult에서도 유형을 수정해야 할 수도 있습니다.

+0

https://gist.github.com/1810229 코드가 있습니다. 나는 네가하는 말을 이해한다고 생각하지만 서명을 고치는 법을 알아 내려고 노력하고있다. – Toymakerii

+0

'applyWindow'에 대한 방법을 추가했습니다. 문제는 로컬 바인딩 이었지만, 모든 배열의 타입을 동일하게하는 것이 바람직합니다. –

+0

뜨거운 젠장! 나는 이틀 동안이 싸움을 해왔다. 나는 다형성 요소 유형을 원했고 FlexibleInstances와 ScopedTypedVariables 주위를 몇 시간 동안 춤을 췄다. 감사합니다! – Toymakerii

2

Data.Array.Unboxed 가져 오기로 배열 (UArray Int Bool)에 대한 명시적인 형식 서명없이 this code을 실행하려고하면 정확히 동일한 오류 메시지 (IArray 등)가 발생했습니다. 서명을 추가하면 모두 괜찮 았어. 아마도 이것은 당신을 도울 것입니다.

+0

이것이 문제인 경우 변환 규칙 pragma에 명시 적으로 존재하지 않는 서명을 추가 할 수 있어야합니다. 어느 정도 성공하지 못 했습니까 – Toymakerii