2012-10-03 112 views
0

我想寫一個函數,將兩個數組的所有元素一起添加並返回一個數組。它輸入了一個雙列表。Haskell簡單類型問題

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

回答

8

我想你在這裏採取了錯誤的做法。通過編寫你隱約理解的函數,直到編譯器停止向你大喊大叫,你不會獲得可靠的addTogether函數。這是危險的,Haskell和C都是這樣的。你可以不使用這些函數,或者你完全閱讀他們的文檔,例子和理想的代碼。這是我的意見。

關於addTogether,有許多不同的方法來實現它。如果您花了一個小時嘗試使用zipmap而沒有任何令人滿意的結果,那麼您可以嘗試其他方法。這裏

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] 

(它不處理無限的名單,我很快就做到了)

@丹尼爾菲捨爾解決方案非常好,但起初uncurry可能有點令人不安。你可以這樣看:

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

我希望它會幫助和對我可憐的英語感到抱歉。

7

的功能,您應該使用有

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

但更好的選擇將是

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

類型的mapM_

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

其中明確做不符合您的預期目的。