2012-02-13 9 views
1

現在、私は私のコードでこのような何かをしています:理解力よりもリストを作成する別の方法はありますか?

--Generate a list of n 'Foo's 
generateFoos n = [createFoo (show i) | i <- [1..n]] 

-- Create a Foo with a given name 
createFoo :: String -> Foo 

[1..n]すべての時間帯を作成するよりも、これを行うための別の方法があれば、私はさまよった...

+0

範囲が悪いのか? – hammar

+0

何もしていませんが、他のやり方があるかどうかを確認するだけです。 – drozzy

答えて

7

私はそれについて心配しないで言う。 「[1..n]の範囲を作成する」は、明確なステップとして実際には進んでいません。その[1..n]enumFromTo 1 nにdesugarsし、それはとにかく他のすべてのようにゆっくりと構築されます。ここに隠す費用はありません。

+2

さらに、 '[1..n]'はリストフュージョンに参加することができるので、リストを完全に削除することができます。 –

2

私はそれを好みますそのように:

generateFoos n = map (createFoo . show) [1..n] 

または範囲自体は問題ですか?それでは、私はお勧めしたい:

generateFoos n = map (createFoo . show) (enumFromTo 1 n) 
+0

私は誰かがこれに 'map'を合わせる方法を考え出すのを知っていました!!! – drozzy

+1

@drozzy:それはかなり明らかです。 'map'が悪いと思うなら、おそらくHaskellはあなたのための適切な言語ではないでしょうか? :P –

+2

@ NiklasB。 'import Data.Humor' – drozzy

6

ここで私のコメントを拡大 - map関数が自然に発生する理由は次のとおりです。 Haskellで

、リストの内包表記を行うためだけ糖衣構文です:

[ 2 * x | x <- [1..10] ] 

は、順番に

do { x <- [1..10]; return (2 * x) } 

に相当し、表記を行うことは単項バインドのためのシンタックスシュガーである - 上記は等価です〜

[1..10] >>= \x -> return (2 * x) 

Listはモナド。モナドにListを行うコードは、私たちがbindへの呼び出しを置き換える場合は、同等である、

concat (map (\x -> return (2 * x)) [1..10]) 

instance Monad [] where 
    return x = [x] 
    xs >>= f = concat (map f xs) 

はそう上記>>=の呼び出しは等価です(一部無関係なものを無視して)されます

concat (map (\x -> [2 * x]) [1..10]) 

にだから我々はリスト[1..10]上で機能\x -> [2 * x]をマッピングしてから呼び出します結果はconcatになります。しかし、我々の関数は唯一、すべての1つの要素のリストを構築するために、我々は

map (\x -> 2 * x) [1..10] 

でコードをCONCATと置き換えるために呼び出しをスキップすることができますので、それは、比較的単純なリストの内包表記はオーバー機能をマッピング伴う表現に変えることができることを自然なことです範囲。

+0

すべてのリスト内包表記は 'map'と' filter'の何らかの組み合わせに "自然に"等しく変換できます。構文砂糖のポイントは、それがより甘いということです。 –

+0

私は同意します。しかし、リストの理解には「魔法」はないことを知ることは有益です。インタプリタ/コンパイラによって、あなた自身で書くことができる普通の古いHaskellに変身しました。リスト内包表記をさまざまな形に変換できることを知っているだけで、より読みやすいコードを書くのに役立ちます。同様に、「do」表記法に代わるものがあることを知ることは、コードの不純な部分を純粋な部分から分離しておくのに役立ちます。 –

+0

私はあなたの主張に同意していません。地図はここで自然です。すべてのあなたの情報は堅実であり、私はあなたの推論に同意します。 –

1

いいえmap、範囲はありません。

generateFoos n = unfoldr (doit (createFoo . show)) 1 where 
    doit f acc = if acc > n then Nothing else Just (f acc, acc + 1) 

でも、私はこのコードのいずれかの特定の品質や財産を保証するものではありません。)

+0

私はunfoldrが大好きです。あまり使用されることはありませんが、強力です。 –

関連する問題