2011-01-23 22 views
10

Giả sử tôi muốn thêm hai danh sách trong Haskell. Cách thông thường nhất để làm điều này là gì?Cách thành ngữ để thêm danh sách trong Haskell là gì?

Dưới đây là những gì tôi đã làm:

addLists :: (Integral a) => [a] -> [a] -> [a] 
addLists xs ys = map add $ zip xs ys 
    where add (x, y) = x+y 
+3

BTW: 'add = uncurry (+)'. Cũng lưu ý rằng câu trả lời 'zipWith' là lần truy cập đầu tiên trên [Hoogle] (http://haskell.org/hoogle/) cho truy vấn [' (a -> b -> c) -> \ [a \] - > \ [b \] -> \ [c \] '] (http://haskell.org/hoogle/?hoogle=%28a+-%3E+b+-%3E+c%29+-%3E+%5Ba% 5D + -% 3E +% 5Bb% 5d + -% 3E +% 5Bc% 5D). – ephemient

+0

Cảm ơn ephemient, tôi sẽ thử Hoogle lần đầu tiên. –

+0

@TomMD, tôi không hiểu phần đầu tiên của nhận xét của bạn. –

Trả lời

28

Có một chức năng zipWith thư viện kết hợp hai danh sách bằng cách sử dụng một chức năng cung cấp. Nó thực hiện chính xác những gì bạn muốn ở đây và bạn nhận được:

addLists = zipWith (+) 

Sử dụng (+) để kết hợp các yếu tố của danh sách.

+0

Aw đánh tôi với nó. –

2
addLists xs ys = zipWith (+) xs ys 
6

applicative functor phong cách:

import Control.Applicative 

addLists xs ys = getZipList $ (+) <$> ZipList xs <*> ZipList ys 

Lưu ý rằng đây là quá xấu xí vì có hai cách để kiếm Danh sách một applicative functor. Cách đầu tiên (và IMHO ít hữu ích hơn) là lấy tất cả sự kết hợp và cách đó trở thành "chuẩn", vì vậy (+) <$> [1,2] <*> [30,40][31,41,32,42]. Một cách khác là nén các danh sách như chúng ta cần ở đây, nhưng vì bạn chỉ có thể có một cá thể kiểu lớp cho mỗi kiểu, chúng ta phải bọc các danh sách trong ZipLists và để bỏ kết quả bằng cách sử dụng getZipList.

Các vấn đề liên quan