2012-02-11 5 views
1

私のプログラムをData.ArrayからData.Array.Unboxedに変換しようとしています。迅速なサイドノートとしてHaskell配列からボックス化されていない配列に変換すると、書き換えルールが破損する

: いくつかの場所は、しかし、私は配列の両方 種類を混合わけではない、私は私のコード に「UArray」への「アレイ」に変更し、Data.Array.Unboxedのインポートを追加できると述べていますだから Data.Arrayの代わりにData.Array.Unboxedをインポートしただけで十分ですか?

私はスイッチ次の書き換えルールの休憩を作る:

ここ
{-# 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,accumArrayarrayなどのような関数をData.Arrayにインポートしただけで使用すると、配列型で単調ですので、あいまいさはありません(要素型の多型は明らかに問題を生じません。タイプのクラス制約)。しかし、Data.Array.Unboxedをインポートした場合、これらの関数はすべてIArray a eという制約を受けます。したがって、書き換えには異なる配列タイプが含まれている可能性があります。タイプシグネチャ、関数、またはルールで型を修正する必要があります。どのように正確にこれを解決するには、コードを見ずに言うことができません。

注:タイプチェックは7.4、ghc-7.4.1で変更されました。ルールを持たないコードは、Data.Array.Unboxedをインポートするとタイプシグネチャなしでコンパイルされません。の2つのローカル束縛に

  • 、ルールが曖昧に実行されないように、あなたがapplyWindowに、型シグネチャにトップレベルの

    • を与える必要があり、種類を修正するには

      paddedImageおよびfilteredPaddedImage

    おそらく希望と最も合理的で

    1. monmorphicタイプにすることができ、同じタイプを持っているすべての関係のアレイのためである、(要素の型もWord可能性UArray (Int,Int) Intを言います...Tである)
    2. 要素タイプ
    3. 1について両方

    における型ploymorphicにおける配列型及び多型における型単相、単に(署名を追加する必要がありapplyWindow :: T -> T -> TxxImage :: T希望のタイプ)。 2.については、次の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になるだろう。 constの出現をconstarintに許可するにはFlexibleContextsが必要であり、paddedImagefilteredPaddedImageがタイプシグネチャをまったく取得できるように、要素タイプを有効範囲にするにはScopedTypeVariablesが必要です。 3.ため、唯一ScopedTypeVariables必要とされる、applyWindowの型シグネチャは、次に、(ローカル未結合)を用いasTypeOfまたはリストにそれらすべてを入れている

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

    別の方法は、同じタイプのすべてのアレイを強制することで、 IMOタイプの署名が望ましいです。

    すべての型が固定されている(必ずしも同じである必要はありませんが、引数と結果の型、場合によっては引数の型だけでローカルバインディングの型を決定する必要があります)。 (indexMultでもタイプを修正する必要があるかもしれません。)

  • +0

    https://gist.github.com/1810229 コードがあります。私はあなたが言っていることを理解していると思いますが、署名を修正する方法を理解しようとしています。 – Toymakerii

    +0

    'applyWindow'の方法を追加しました。問題はローカルバインディングでしたが、すべての配列を同じ型にすることはおそらく望ましいことです。 –

    +0

    ホット・ダン!私はこれで2日間これと戦ってきました。多相要素タイプが欲しかったので、FlexibleInstancesとScopedTypedVariablesの周りを何時間も踊っていました。ありがとうございます! – Toymakerii

    2

    私はちょうどData.Array.Unboxedインポートを、私は(その場合UArray Int Bool)アレイのための明示的な型シグネチャなしthis codeを実行しようとした(IArray等について)まったく同じエラーメッセージを受信しました。私が署名を加えたとき、すべてはOKだった。多分これもあなたを助けるでしょう。

    +0

    これが問題であれば、私は変換ルールプラグマ内に明示的な非存在シグニチャを追加できる必要があります。私は成功していません – Toymakerii

    関連する問題