たとえば、数字のリストがあり、各数字に 2 と 3 を掛けたものを含むリストを作成したいとします。次のようなことを行う方法はありますか?数のリストのリスト?
mult_nums = [ [(n*2),(n*3)] | n <- [1..5]]
-- this returns [[2,3],[4,6],[6,9],[8,12],[10,15]]
-- but we want [2,3,4,6,6,9,8,12,10,15]
たとえば、数字のリストがあり、各数字に 2 と 3 を掛けたものを含むリストを作成したいとします。次のようなことを行う方法はありますか?数のリストのリスト?
mult_nums = [ [(n*2),(n*3)] | n <- [1..5]]
-- this returns [[2,3],[4,6],[6,9],[8,12],[10,15]]
-- but we want [2,3,4,6,6,9,8,12,10,15]
リスト内包表記を拡張すると、これが読みやすくなることがわかりました。
[ m | n <- [1..5], m <- [2*n,3*n] ]
これが何をするのか、そしてそれが他のソリューションとどのように関連しているかを正確に調べることが役立つかもしれません。それを関数として定義しましょう:
mult lst = [ m | n <- lst, m <- [2*n,3*n] ]
ファッションの後、これは脱糖します
mult' lst =
concatMap (\n -> concatMap (\m -> [m]) [2*n,3*n]) lst
式concatMap (\m -> [m])
はm
、すぐにフラット化するためにリストにまとめられています。これは、と同等map id
です。
これを@FunctorSaladの答えと比較してください:
mult1 lst = concatMap (\n -> [n*2,n*3]) lst
最適化しましたconcatMap (\m -> [m])
。
今@viliの答え:
mult2 lst = concat [ [(n*2),(n*3)] | n <- lst]
これは次のように脱糖します:
mult2' lst = concat (concatMap (\n -> [[2*n,3*n]]) lst)
上記の最初のソリューションと同様に、削除する必要のあるリストのリストを不必要に作成してconcat
います。
リスト内包表記を使用する解決策はないと思いますが、脱糖しmult1
ます。私の直感では、Haskellコンパイラーは一般的に十分に賢いので、これは問題になりません(あるいは、concat
遅延評価のために不要なものは安価です(熱心な言語では致命的です))。
concat を使用できます。
concat [ [(n*2),(n*3)] | n <- [1..5]]
output: [2,3,4,6,6,9,8,12,10,15]
同様のケースでは、concatMap も便利ですが、ここではあまり変わりません。
concatMap (\n -> [n*2,n*3]) [1..5]