[英]List all combinations of a list of lists where no two elements are the same
[英]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 (,)
相同,並且在列表concatMap
, concatMap
函數, >>=
, <$>
和<*>
運算符方面進行了各種重寫。
從概念上講,雖然這是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.