<div dir="ltr">@Silent Leaf<div><br></div><div>I am indeed familiar with the list comprehension syntax indeed. I agree with you that it certainly is the better alternative to writing handcrafted functions especially when they involve (++). However the code you have mentioned doesn't get the job done correctly. Your approach implements a square nested loop which makes it at least twice as inefficient than the one I am rooting for. The problem lies with the dropWhile function. It will begin from the start of the list for every new (x,ix). This is particularly bad in Haskell because the garbage collector cannot do away with unnecessary prefixes of the input string, thereby wasting a lot of memory.</div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature"><div dir="ltr"><div><br><br><br>Rohan Sumant<br> </div></div></div></div>
<br><div class="gmail_quote">On Sun, Apr 10, 2016 at 11:42 PM, Silent Leaf <span dir="ltr"><<a href="mailto:silent.leaf0@gmail.com" target="_blank">silent.leaf0@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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" target="_blank">https://wiki.haskell.org/List_comprehension</a><br></div><br></div>
<br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div></div>