簡體   English   中英

Haskell中兩個列表的元素的所有組合

[英]All combinations of elements of two lists in Haskell

鑒於兩個列表, [a, b][c, d] ,我想得到以下結果:

[(a,c), (a,d), (b,c), (b,d)]

我怎么能在Haskell中做到這一點? 是否有內置功能,或者我應該自己實現?

[ (x,y) | x<-[a,b], y<-[c,d] ]

這不需要任何進一步的解釋,是嗎?

應用風格一路走來!

λ> :m + Control.Applicative
λ> (,) <$> ['a','b'] <*> ['c','d']
[('a','c'),('a','d'),('b','c'),('b','d')]

(我已經避開上面的任何String語法糖,以便保持接近你的榜樣。)

有關信息, (,)是一個函數的特殊語法,它接受兩個參數並從中生成一對:

λ> :t (,)
(,) :: a -> b -> (a, b)

編輯:正如評論中 左下角所述 ,你也可以使用liftA2

λ> :m + Control.Applicative
λ> let combine = liftA2 (,)
λ> combine "ab" "cd"
[('a','c'),('a','d'),('b','c'),('b','d')]

你怎么能在命令式偽代碼中做到這一點?

for each element x in [a,b]:
    for each element y in [c,d]:
        produce (x,y)

在Haskell中,這是寫成的

outerProduct xs ys =
   do
       x <- xs          -- for each x drawn from xs:
       y <- ys          --   for each y drawn from ys:
       return (x,y)     --      produce the (x,y) pair

(左下方的評論)這當然非常接近liftM2組合器的定義,所以實際上

outerProduct = liftM2 (,)

它與liftA2 (,)相同,並且在列表concatMapconcatMap函數, >>=<$><*>運算符方面進行了各種重寫。

從概念上講,雖然這是Applicative - 它可以更好地命名為Pairing , - 因為這兩個“容器”/“載體”的元素配對/無論是Applicative Functor究竟是什么。 它只是恰巧,Haskell的do記號適用於單子,而不是( 為applicatives

在某種意義上, 編譯時嵌套循環 Applicative / Pairing仿函數; Monads添加了動態創建嵌套循環的功能,具體取決於“外部”枚舉產生的值。

最直觀的是使用列表理解,其他aproaches包括使用applicative functors:

(,) <$> [1,2,3] <*> [4,5,6]

那這是做什么的呢?

記住(,) :: a -> b -> (a, b)取兩個參數並返回一個元組。

<$>是非常fmap, (<$>) :: Functor f => (a -> b) -> fa -> fb它需要一個函數並解除它。 在這種情況下,它需要(,)並將其提升到列表上。 所以let x = (,) <$> [1,2]生成x :: [b -> (Integer, b)]這是帶有b的函數列表,並返回帶有一個固定參數的元組(整數, b)。 最后,我們使用<*>來應用它來生成所有組合。

使用列表理解:

s = [a,b]
s' = [c,d]

all_combinations = [(x,y) | x <- s, y <- s']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM