Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Haskell将列表的唯一组合添加到元组_List_Haskell_List Comprehension - Fatal编程技术网

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:|