2012-02-11 23 views
1

我想將我的程序從使用Data.Array轉換爲Data.Array.Unboxed。Haskell從數組轉換到Unboxed數組中斷重寫規則

作爲一個邊注: 幾個地方指出,我可以在我的代碼 「陣列」更改爲「UArray」,並添加Data.Array.Unboxed的進口,但是我不混合兩種 類型的數組所以 我剛剛導入Data.Array.Unboxed而不是Data.Array,這足夠嗎?

當我做了開關以下重寫規則遊:

{-# 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.UnboxedData.Array.IArray,因此IArray類不可改變陣列接口,但Data.Array不(它甚至不導入)。所以如果你使用的函數如bounds,accumArray,array等僅僅輸入了Data.Array,它們在數組類型中是單形的,因此不會出現模糊性(元素類型中的多態性在這裏顯然不會造成問題,它會適用於類型的類約束)。但是,如果導入Data.Array.Unboxed,則所有這些函數都會得到一個約束,因此重寫可能涉及不同的數組類型,因此會中斷。你需要修改類型簽名的類型,函數或整數規則。如何解決這個問題我不能說沒有看到代碼。

注意:類型檢查已更改爲7.4,使用ghc-7.4.1時,如果導入Data.Array.Unboxed,則沒有規則的代碼不會在沒有類型簽名的情況下進行編譯。

要解決的類型,因此該規則不運行的不確定性,你必須給類型簽名

  • 在頂層,以applyWindow
  • 到兩個本地綁定paddedImagefilteredPaddedImage

的可能需要的和最合理的是,所有涉及陣列具有相同的類型,可以

  1. 一個monmorphic類型,說UArray (Int,Int) Int(元素類型也可能是Word,...)
  2. 在陣列類型的類型單形和多晶型中的元素類型
  3. 在兩個

對於1.一種ploymorphic,你只需要添加的簽名,和applyWindow :: T -> T -> TxxImage :: T(其中T是期望的類型)。對於2,你必須添加兩個語言擴展,FlexibleContextsScopedTypeVariables,然後applyWindow會得到簽名

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

和本地綁定會得到簽名xxImage :: UArray (Int,Int) e。需要FlexibleContexts以允許在常數中出現UArray,並且ScopedTypeVariables對於使元素類型進入作用域是必要的,因此paddedImagefilteredPaddedImage完全可以獲得類型簽名。對於3,僅ScopedTypeVariables是必要的,的applyWindow類型簽名將被

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

另一種方法強制所有陣列以相同的類型是使用asTypeOf或將它們全部放入一個列表(未使用的本地綁定),但IMO類型簽名更可取。

一旦所有類型都固定(它們不一定必須相同,但本地綁定的類型必須由參數和結果類型(可能僅包含參數類型)確定),則規則應該鍵入檢查。 (可能需要修復indexMult中的類型。)

+0

https://gist.github.com/1810229 有代碼。我想我明白你在說什麼,但我有一段時間試圖弄清楚如何修復簽名。 – Toymakerii 2012-02-12 18:54:00

+0

增加了一個'applyWindow'的方法,問題是本地綁定,但讓所有數組具有相同的類型可能是可取的。 – 2012-02-12 20:04:19

+0

熱Dam!我已經打了兩天了,我想要多態元素類型,並且在FlexibleInstances和ScopedTypedVariables上跳舞數小時。謝謝你,先生! – Toymakerii 2012-02-12 20:10:16

2

我收到完全相同的錯誤消息(約IArray等),當我試圖不爲(在這種情況下UArray Int Bool)數組明確的類型簽名運行this code,剛剛與Data.Array.Unboxed進口。當我添加簽名時,一切正常。也許這也會對你有所幫助。

+0

如果這是問題,我需要能夠在翻譯規則編譯指示中添加顯式非存在簽名。其中我沒有成功做 – Toymakerii 2012-02-12 03:24:16