0

2つの配列のすべての要素を足し合わせて、1つの配列を返す関数を作成しようとしています。重複したリストを入力します。

addTogether :: Num t => ([t],[t]) -> [t]
addTogether (x, y) = mapM_ (\ (a, b) -> a + b) (zip x y)
4

2 に答える 2

8

ここであなたは間違ったアプローチをしていると思います。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

それが助けになることを願っており、私の下手な英語について申し訳ありません.

于 2012-10-03T04:18:29.353 に答える
7

そこで使うべきだった機能は

map :: (a -> b) -> [a] -> [b]

しかし、より良い選択は

addTogether :: Num t => ([t], [t]) -> [t]
addTogether = uncurry (zipWith (+))

のタイプmapM_

mapM_ :: Monad m => (a -> m b) -> [a] -> m ()

これは明らかに意図した目的を果たしません。

于 2012-10-03T01:19:14.100 に答える