2012-09-03 13 views
14

我々は自動的融合のこの種の実行上の任意のreasearchがありますので、同じリストで2つのマップを融合するにはどうしたらいいですか?

unzip (map (\x -> (f x, g x)) xs) 

のように表現

(map f xs, map g xs) 

にリストxsにわたって2つの横断を融合だろうか?

(返されたリストの一方が他方の前に消費された場合は、ここでスペースリークを作成するにはリスクがあります、私はスペースを節約するよりもxsの上に余分な横断を防止する上でより興味があります。。)

編集:I unzipがその消費者と融合できるかどうかによっては、この変換が意味をなさないかもしれない実際のメモリ内Haskellリストに融合を適用することを実際には考えていない。私はunzipが融合できることを知っている設定をしています(「FlumeJava:簡単で効率的なデータ並列パイプライン」を参照)。

+2

とにかく、自動ではありませんが、かなりいいです:http://squing.blogspot.com/2008/11/beautiful-folding.html –

+1

この結果が他のものと融合しない限り、ペアを作成してそれらを解凍するオーバーヘッドは、余分なトラバースのコストよりも大きくなる。 – augustss

+1

@augustssトラバーサルが巨大なファイルを上回っていない場合は!私はこれを実際のリストに適用するつもりはない。 – tibbe

答えて

4

また、完全自動ではありませんが、GHCにそのような書き換えルールのリストを与えることができます。 7.14 Rewrite rulesおよびUsing rulesを参照してください。次にコンパイラはこれらの規則を使用して、コンパイル時にプログラムを最適化します。 (決してチェックでコンパイラはルールがどんな意味をなす場合があります。)

編集:は、この特定の問題のための例を与えるために、我々は書くことができます。

{-# OPTIONS_GHC -fenable-rewrite-rules -ddump-rule-firings -ddump-rule-rewrites #-} 

import Data.Char 

{-# RULES 
"map/zip" forall f g xs. (,) (map f xs) (map g xs) = unzip (map (\x -> (f x, g x)) xs) 
    #-} 

main :: IO() 
main = let x = "abCD" in 
     print $ (,) (map toUpper x) (map toLower x) 

(トップレベルをルールの関数名は(,) :: a -> b -> (a, b)です)。コンパイルすると、ルールの適用方法がわかります。オプションdump-rule-firingsはルールが適用されたときにメッセージを表示し、-ddump-rule-rewritesは各ルールアプリケーションを詳細に表示します。7.14.6. Controlling what's going on in rewrite rulesを参照してください。

ヨーゼフSvenningsson:

+0

私は、これらの種類の表現に一致するルールを書くことはできないと思います。 GHCルールは関数名で始まる必要があります。 – tibbe

3

私は、少なくとも簡単に融合(未)に言及して関数のように郵便番号の2つのリソースを、見つけることができました。 「パラメータを累積するためのショートカットフュージョン&ジップライクな機能」 http://www.cse.chalmers.se/~josefs/publications/fusion.pdf

ダンカンCoutts。 "ストリームフュージョン:誘導シーケンスタイプのための実用的なショートカットフュージョン" https://community.haskell.org/~duncan/thesis.pdf

いずれのリソースも、この種の「兄弟融合」を明示的に言及していません。

+1

私はこのプレゼンテーションを見ませんでしたが、[TupleFusion](http://wiki.portal.chalmers.se/cse/uploads/FP/Josef_TupleFusion.pdf)に関するJosefのスライドです。 – danr

+0

[自動チューリング戦略に向けて](http://dl.acm.org/citation.cfm?id=154643)が面白いかもしれません。 –

関連する問題