2012-04-18 3 views
5

タプルは自然な型であると考えているので、タプルに複数の値を集めることがよくあります。ただし、タプルは厳密ではありません。したがって、考慮することGHCのネストされたUNPACK

data A 

data B = 
    B !A 

data C = 
    C !(B, B) 

data D = 
    D !B !B 

-funbox-strict-fieldsと最適化では、UNPACKはネストされています。 Cのタプルは、DのようにC A Aに解凍されるか、またはC B Bとなるでしょうか? GHC-docの参考資料は7.16. Pragmasです。

(??タイプのコンストラクタ空でないタプルタイプある)

答えて

6

考えてみましょう:

data (,) a b = (a,b) 

GHCは喜んでネストされた、厳格なコンストラクタに(!B)が消去されます

data B = B !Int 

data C = C !(B, B) 

data D = D !B !B 

b0 = B 7 
b1 = B 4 

c = C (b0, b1) 

d = D b0 b1 

、最初のフィールドでCが厳密になり、次のように最適化されます。

b0 = B 7 
b1 = B 4 

c = C b0 b1 

d = D 7 4 

しかし、重要なことに、(,)のフィールド自体は厳密ではないため、GHCはそれらをアンパックできません。さらに、それらは多形であるため、厳格であってもそれらを解凍することはできません。

最初の部分の回避策は、厳密なタプルを使用することです。 2番目の部分の回避策は、self-specializing tuplesを使用することです(タプルを特化したファミリを入力するなど)。


(注)このスタイルで構文については、タプルを使用すると、オーバーヘッドが発生していること - 彼らは離れて最適化する必要が間接的なレベルをご紹介します。したがって、それはやや独立したものです。

+0

私の質問でエラーが修正されました。データBはデータB = B!Aでなければなりません。だからCでは、タプルの代わりに厳密なフィールドを持つ独自の特殊型を使うべきですか?私はGHCがタプルを見つけた後も引き続き展開できることを期待していたので、各フィールドに特化した多くのデータ型を書く必要はありません。 (しかし、私はタプルで値を集めるので、おそらく値の集合の抽象的な考えがあるので、おそらく特殊なバージョンを使うべきです...) – telephone

+0

タプルが多形でない場合は、私は以前この問題について書きました:http://donsbot.wordpress.com/2009/10/11/self-optimizing-data-structures-using-types-to-make-lists-faster/ –

+0

私が見てきたようにデータ型の厳密なフィールドとして使用されるGHC-docの例が平坦化されます。 – telephone

関連する問題