1

非常に一般的なUArrayを使用して関数を作成しようとしています。型署名が欲しいのですが:

myFunction :: a -> b -> ((UArray Int a), (UArray Int b))

ただし、aとbは一般的すぎます。それらをの可能なインスタンスの1つにしたいと思いますIArray UArray a。これを指定できる派生タイプはありますか?たとえば、Numが有効なインスタンスである場合、次のことができます。

myFunction :: (Num a, Num b) => a -> b -> ((UArray Int a), (UArray Int b))

私がやろうとしていることは理にかなっていますか?

前もって感謝します!

4

1 に答える 1

5

使用する配列メソッドなどから制約を繰り返す必要がありarrayます。インデックスは固定されており、インスタンスであることがわかっているため、制約Ixを追加するだけで済みます。IArray

myFunction :: (IArray UArray a, IArray UArray b)
           => a -> b -> ((UArray Int a), (UArray Int b))

このためには、FlexibleContexts(セクション7.6.3.2。インスタンスコンテキストの緩和されたルールを参照)言語拡張が必要です。

UArray関数を任意の配列に一般化することも考えられます(

myFunction1 :: (IArray arr a, IArray arr b)
            => a -> b -> ((arr Int a), (arr Int b))

またはおそらく任意のインデックスに:

myFunction2 :: (IArray arr a, IArray arr b, Ix i)
            => a -> b -> ((arr i a), (arr i b))

(これら2つのバリアントの場合、拡張子は必要ありません。)

おそらくUArray速度のためにsを使用しているので、プラグマを追加INLINEして、使用する場所の特定のデータ型に対して関数が最適化されるようにすることをお勧めします。これにより、速度が大幅に向上します。

于 2013-01-29T23:35:36.823 に答える