2011-12-16 8 views
6

私はかなり多くの場所に現れるかなり一般的なハスケルの定型文を持っています。 (クラスをインスタンス化するとき)には次のようになります。この(通常の機能を持つ)のような一般的なhaskellパイピングのボイラープレートを削除する

a <= b = (modify a) <= (modify b) 

:でもタプルと

fn x y z = fn (foo x) (foo y) (foo z) 

、時には、のように:

mod (x, y) = (alt x, alt y) 

それをこのボイラープレートのすべてを減らす簡単な方法があり、自分自身を非常に多く繰り返す必要はないようです。 (これらは簡単な例ですが、迷惑になります)。私はそのような定型文を削除するために作成された抽象概念があると想像していますが、私は彼らが何を呼んでいるのか、どこを見ているのかは分かりません。どんなhaskellitesでも正しい方向に私を向けることができますか?定型のいくつかについては

答えて

12

(<=)ケースの場合を獲得しませんが、参考に代わりcompareを定義することを考慮することができます。あなたはそのようにように、Data.Ord.comparingを使用することができます。comparingは、単にData.Function.onを使用して、comparing f = compare `on` fとして定義することができることを

instance Ord Foo where 
    compare = comparing modify 

注意を。

fnの例では、明確ではありません。この種の定義を一般的に単純化する方法はありません。しかし、この例では定型文があまりにも悪いとは思わない。 modについて

Control.Arrow.(***)を用い
mod = alt *** alt 

- 型シグネチャにb -> cとしてa b cを読み取ります。矢印は関数がインスタンスである一般的な抽象(ファンクタやモナドのような)に過ぎません。 both = join (***)(それ自体はboth f = f *** fの省略形です)を定義することもできます。私はこのエイリアスを使用する少なくとも1人の他の人を知っています、そして、私はそれが制御にあるべきだと思います。

したがって、一般的な答えは、コンビネータ、コンビネータ、コンビネータです。これは直接point-freeスタイルで結びついています。あなたの状況に合ったコンビネータが存在する場合、そのようなコードはより洗練され、短くなるだけでなく、読みやすくなります。抽象度を一度学ぶだけで、コードを読むときにどこにでも適用できます。

Hoogleを使用してこれらのコンビネータを見つけることをお勧めします。定義の根底にある一般的なパターンが見えると思ったら、共通の部分が何であるかを抽象化し、結果のタイプを取り出し、Hoogleで検索してみてください。あなたはあなたが望むだけのコンビネータを見つけるかもしれません。完全一致がありますが、それはあなたがしたくないこれ、FGLグラフライブラリにだ -

だから、例えば、あなたのmod場合のために、あなたは\f (a,b) -> (f a, f b)を得altアウト抽象的、そして、そのタイプに(a -> b) -> (a, a) -> (b, b)を検索できます拠り所にする。それでも、タイプ別に検索する機能がどのように実際に非常に貴重なものになるかを確認できます。

また、GHCi統合のコマンドラインバージョンのHoogleもあります。詳細はHaskellWiki pageを参照してください。

(もHackageの全体を検索しますが、種類とわずかに少ない賢いですHayoo、あります;。個人の好み次第ですあなたが使用している1)

4

Data.Function.onはこれらの例には、それは非常に

instance Ord Foo where 
    (<=) = (<=) `on` modify -- maybe 

mod = uncurry ((,) `on` alt) -- Not really 
関連する問題