I've run in to a few situations where I need the list:
[(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)] -- no (0,0)
Note that there is no (0,0) in the list. I use the (dx,dy) tuples to search up, down, left, right and diagonally from a coordinate.
Every time I write it I feel like there should be a more concise, and/or easier to read way to define it. I'm relatively new to Haskell and I figure somewhere in the bag of Applicative/Functor/Monad tricks there should be a neat way to do this.
I've tried:
[(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
Sometimes it's better just to write it out, but I don't think this is one of those times. It's not obvious with a glance that (0,0) isn't included, and you have to read it a bit to notice the pattern.
map (\[a,b] -> (a,b)) $ delete [0,0] $ sequence $ replicate 2 [-1,0,1]
I like the one above because I get to put the "2" in there which is a nice explicit way to say "We're doing the same sort of thing twice", but I can't accept the map in front with the big unsafe lambda and 2 names.
[(dx,dy) | let a = [-1,0,1], dx <- a, dy <- a, (dx,dy) /= (0, 0)]
This one has too many names in it, but uses the list comprehension exactly as it is designed. It might be easier to read for somebody who really likes list comprehensions, but I don't like all the names.
let x = [-1,0,1] in delete (0,0) $ (,) <$> x <*> x
That one looks prettier imo, but I don't have that "2" in there, and I have a name. This is my favorite so far, but it doesn't feel perfect.
I think if I understood how to write this better I might have a deeper understanding of Functors/Monads or the like. I've read about them quite a bit, and I've heard a bunch of words like fmap/mconcat/etc, but I don't know which one to grab for in this situation.