List Haskell将列表的唯一组合添加到元组
比如说,我有一个这样的列表List Haskell将列表的唯一组合添加到元组,list,haskell,list-comprehension,List,Haskell,List Comprehension,比如说,我有一个这样的列表 list = ["AC", "BA"] 我想将此列表的每个唯一组合添加到一个元组中,因此结果如下: [("AC", "AC"),("AC","BA"),("BA", "BA")] ya = [(x,y) | x <- list, y <- list] 其中不包括(“BA”、“AC”) 我的第一种方法是使用如下列表理解: [("AC", "AC"),("AC","BA"),("BA", "BA")] ya = [(x,y) | x <- lis
list = ["AC", "BA"]
我想将此列表的每个唯一组合添加到一个元组中,因此结果如下:
[("AC", "AC"),("AC","BA"),("BA", "BA")]
ya = [(x,y) | x <- list, y <- list]
其中不包括(“BA”、“AC”)
我的第一种方法是使用如下列表理解:
[("AC", "AC"),("AC","BA"),("BA", "BA")]
ya = [(x,y) | x <- list, y <- list]
ya=[(x,y)| x只需使用列表理解:
f :: (Ord a) => [a] -> [(a, a)]
f list = [ (a, b) | a <- list, b <- list, a <= b ]
ThreeFx的答案是可行的,但它增加了元素必须可排序的约束。相反,您可以使用Prelude
和Data中的函数。List
可以更有效、更一般地实现这一点:
import Data.List (tails)
permutations2 :: [a] -> [(a, a)]
permutations2 list
= concat
$ zipWith (zip . repeat) list
$ tails list
它不使用列表理解,但它不需要执行潜在的昂贵比较,也不需要对可以输入的值类型进行任何限制
看看它是如何工作的,考虑如果你有列表<代码>(1, 2, 3)< /代码>,你会有组
[(1, 1), (1, 2), (1, 3),
(2, 2), (2, 3),
(3, 3)]
这相当于
[(1, [1, 2, 3]),
(2, [2, 3]),
(3, [3])]
因为它不包含任何额外或更少的信息。从这种形式到我们想要的输出的转换是映射函数f(x,ys)=map(\y->(x,y))ys
覆盖每个元组,然后将它们聚集在一起。现在我们只需要弄清楚如何获取这些元组的第二个元素。很明显,我们看到它所做的一切都是从列表的前面删除连续的元素。幸运的是,Data.listtails
函数已经为我们实现了这一点ode>。每个元组中的第一个元素只是组成原始列表,因此我们知道可以使用zip
。最初,您可以使用
> concatMap (\(x, ys) -> map (\y -> (x, y)) ys) $ zip list $ tails list
但我个人更喜欢zip
s,因此我会将内部函数转换为不使用lambdas的函数:
> concatMap (\(x, ys) -> zip (repeat x) ys) $ zip list $ tails list
由于我更喜欢带f的zipWith
而不是map(uncurry f.zip)
,我会把它变成
> concat $ zipWith (\x ys -> zip (repeat x) ys) list $ tails list
现在,我们可以进一步减少:
> concat $ zipWith (\x -> zip (repeat x)) list $ tails list
> concat $ zipWith (zip . repeat) list $ tails list
感谢eta的减少和函数的组合。我们可以让它完全没有任何意义
> permutations2 = concat . ap (zipWith (zip . repeat)) tails
但是我发现这很难阅读和理解,所以我想我还是坚持以前的版本。我首选的解决方案是使用列表理解
f :: [t] -> [(t, t)]
f list = [ (a,b) | theTail@(a:_) <- tails list , b <- theTail ]
f::[t]->[(t,t)]
f list=[(a,b)| tail@(a:|)因此对于一个三元素列表[1,2,3]
,您希望输出[(1,1,(1,2),(1,3),(2,2),(2,3),][/code>?没错!谢谢您的编辑!对于列表中的每个元素,将其自身和所有元素配对:f xs=[(x,y)|ys@(x:|