2012-03-13 48 views
5

Tôi muốn một hàm lấy hai danh sách thuộc bất kỳ loại nào và trả về một danh sách (ví dụ: f:: [[a]] -> [[a]] -> [[a]]). Về cơ bản, quá sản xuất 'ghép nối' của hai danh sách đầu vào.Ghép nối các danh sách trong Haskell

ví dụ:

> f [[1,2,3], [123]] [[4,5,6], [3,7]] 
[[1,2,3,4,5,6], [1,2,3,3,7], [123,4,5,6], [123,3,7]] 

Tôi hiện đã có này xa với nó:

f _ [] = [] 
f [] _ = [] 
f (xs:xss) (ys:yss) = ((xs ++ ys) : [m | m <- f [xs] yss]) 

Nhưng điều này không đưa vào tài khoản xss và là sai. Bất kỳ đề xuất?

Trả lời

9

Đó là một sản phẩm Descartes, vì vậy bạn chỉ cần sử dụng một danh sách hiểu để làm mọi thứ.

Prelude> let xs = [[1,2,3], [123]] 
Prelude> let ys = [[4,5,6], [3,7]] 
Prelude> [x ++ y | x <- xs, y <- ys] 
[[1,2,3,4,5,6],[1,2,3,3,7],[123,4,5,6],[123,3,7]] 
3
import Control.Applicative 

(++) <$> [[1,2,3], [123]] <*> [[4,5,6], [3,7]] 
[[1,2,3,4,5,6],[1,2,3,3,7],[123,4,5,6],[123,3,7]] 
+10

hoặc chỉ 'liftA2 (++)' – luqui

3
f l1 l2 = [x ++ y | x <- l1, y <- l2] 
+0

Làm cách nào tôi bỏ lỡ điều này!?! Kicking bản thân mình. Công cụ cơ bản cơ bản! –

2

Trong Alternative:

import Control.Applicative 

f :: (Applicative f, Alternative g) => f (g a) -> f (g a) -> f (g a) 
f = liftA2 (<|>) 
1
f a b = map concat . sequence $ [a,b] 

Cân lên để kết hợp bất kỳ số lượng danh sách.

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