Haskell マップ/zip vs.リスト内包表記
-
02-10-2019 - |
質問
次のうち、あなたが書く可能性が最も高いのはどれですか?
r = zip xs $ map sqrt xs
または
r = [(x, sqrt x) | x <- xs]
インターネット上のサンプル コードは、前者の方が豊富であり、推奨される方法であることを示しているようです。
解決
私はおそらく書くでしょう
map (\x -> (x, sqrt x)) xs
ポイントフリーを好む場合、上記は(インポートした後の後に相当します Control.Monad
と Control.Monad.Instances
)
map (ap (,) sqrt) xs
まだ言及されていないもう1つの選択肢はありません
zipWith (,) xs (map sqrt xs)
他のヒント
#haskellで時間をかけすぎる人はおそらくそれを書くでしょう
r = map (id &&& sqrt) xs
(&&&)
で定義された楽しいコンビネーターです Control.Arrow
. 。実際のタイプの署名は、矢印のすべてのインスタンスに一般化されているため、複雑です。しかし、それはしばしばに使用されます (->)
のインスタンス Arrow
, 、このタイプの署名になります:
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
私はそれらを頻繁に使用しない傾向がありますが、この場合、私はそれが私にとってきれいに思えるので、私はリスト理解バージョンを好むと思います。
あなたがポイントフリースタイルに興味があるなら、あなたもこれが好きかもしれません:
f = zip `ap` map sqrt
APはControl.monad.monadに住んでいて、この場合、それはSominatorと考えることができます。 スキー計算:
ap f g x == f x (g x)
ap const const == id
Conalが指摘しているように、これはMonadからApplicativeに一般化される可能性があります。
f = zip <*> map sqrt
私はおそらく書くでしょう map
/zip
そして、後で私がリストの理解を書いていたらいいのにと思います。
特定のタイプの問題について(プロジェクトオイラー 特に)、この特定のケースが頻繁に出てくるので、私は次の小さなヘルパーを書きました:
with :: (a -> b) -> a -> (a,b)
with f a = (a, f a)
これにより、例を書くことができます。
r = map (with sqrt) xs
私はどちらかというと「オールドスクール」ハスケリエ派なので、 zip `ap` map sqrt
そして後でそれをリファクタリングして使用します <*>
の代わりに ap
.
Applicative は新しいモナドです。(「最近の Cool Haskell Kids は何を使っているの?」という意味)
私はめったにリストの概念を使用しませんが、どちらもダンディです。コードを読みやすくするものを使用してください。