2つの配列のすべての要素を足し合わせて、1つの配列を返す関数を作成しようとしています。重複したリストを入力します。
addTogether :: Num t => ([t],[t]) -> [t]
addTogether (x, y) = mapM_ (\ (a, b) -> a + b) (zip x y)
ここであなたは間違ったアプローチをしていると思います。addTogether
コンパイラが怒鳴るのをやめるまで、漠然と理解している関数を構成しても、信頼できる関数は得られません。これは一種の危険であり、これは Haskell だけでなく C にも当てはまります。これらの関数を使用しないか、ドキュメント、例、理想的にはそれらのコードをよく読んでください。それが私の意見です。
についてaddTogether
は、さまざまな実装方法があります。1 時間かけて使用zip
してmap
も満足のいく結果が得られない場合は、別の方法を試すことができます。たとえば、それがあなたのものなら、再帰的な方法で処理できます。
addTogether :: Num t => ([t], [t]) -> [t]
addTogether ([],_) = []
addTogether (_,[]) = []
addTogether ((x:xs),(y:ys)) = (x + y):addTogether (xs,ys)
ここに曖昧さはありません。リスト内包表記を使用することもできます (リストを作成したいですか?)。これは次のようになります。
addTogether :: Num t => ([t],[t]) -> [t]
addTogether (x, y)
| null x || null y = []
| otherwise = [ a + b | n <- [0..min (length x) (length y) - 1],
let a = x!!n,
let b = y!!n]
(無限リストは扱いません、私はすぐにやりました)
@Daniel Fischerのソリューションは非常に優れていuncurry
ますが、最初は少し戸惑うかもしれません。次のように表示できます。
addTogether :: Num t => ([t],[t]) -> [t]
addTogether (x, y) = zipWith (+) x y
それが助けになることを願っており、私の下手な英語について申し訳ありません.
そこで使うべきだった機能は
map :: (a -> b) -> [a] -> [b]
しかし、より良い選択は
addTogether :: Num t => ([t], [t]) -> [t]
addTogether = uncurry (zipWith (+))
のタイプmapM_
は
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
これは明らかに意図した目的を果たしません。