<div dir="ltr"><div><div><div><div>Dunno if that's what you're interested in, or if it's best in terms of efficiency, but there's syntax inside the language made just for this kind of thing, called list comprehension. It comes from math's definition of sets by comprehension, and since it's part of the language I'd have a tendency to trust its efficiency, but I might be entirely wrong on this aspect.<br><br></div>Anyways, for your problem, say I want to create the set of pairs of your example:<br><br></div></div>let result = [(x,y) | let xs = [1,2,3,0], (x,ix) <- zip xs [1,2..], y <- drop ix xs, x /= y]<br></div><div>in result == [(1,2),(1,3),(1,0),(2,3),(2,0),(3,0)]</div><div><br></div><div>Basically the syntax is: [ parameterized result element | conditions on the parameters]<br></div><div>the conditions being a sequence of comma-separated items that are either: local variable declarations without the 'in', example being (let input = [1,2,3,0]), pattern-accepting generation of values from a list, or conditions on the parameters (here x and y).<br><br></div><div>In order to build y's list I decided to zip xs with a list of indexes starting to 1, thereby ensuring no pair is twice in, considering the order doesn't matter.<br></div><div>I'd bet the syntax is monad/do related, with all those right-to left arrows. Plus it fits the bill of what's actually happening here.<br><br></div><div>Of course if you want a function, you can still write thereafter<br></div><div>mkpairs :: Integral a => a -> [(a,a)]<br></div><div>mkpairs n = [(x,y) | let xs = [1..n] ++ [0], (x,ix) <- zip xs [1,2..], y <- drop ix xs, x /= y]<br><br></div><div>If you don't care about the order, I guess xs = [0..n] will be much more efficient, relatively speaking.<br></div><div>Pretty sure the function even works for n == 0, since y <- drop 1 [0] won't have a thing to yield, hence, result = [].<br></div><div><br>If that interests you:<br><a href="https://wiki.haskell.org/List_comprehension">https://wiki.haskell.org/List_comprehension</a><br></div><br></div>