Returning a list of every possible coordinate in a grid of that width and height
Asked Answered
M

3

9

So I am writing a function allCoords that returns a list of every possible coordinate in a grid of width w and height h Both width and height must be non-negative integers in order to return a sensible result.

Example: allCoords 3 2 should return [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)]

This is all I've got so far but I don't know how to even start writing the function

type GridCoord = (Int, Int)

allCoords :: Int -> Int -> [GridCoord]
Mousetail answered 18/9, 2020 at 12:1 Comment(1)
edits should not invalidate existing answers. if you already "have it" then what would be the question?Cleek
P
9

You could do that using a list comprehension.

[ (x,y) | x <- [0..1], y <- [0..2] ]

Will give the list in your example.

Your function would then need to be defined as:

type GridCoord = (Int, Int)

allCoords :: Int -> Int -> [GridCoord]
allCoords height width = [ (x,y) | x <- [0..width-1], y <- [0..height-1] ]
Peroxide answered 18/9, 2020 at 12:13 Comment(0)
J
4

The range function does that.

import Data.Ix
allCoords h w = range ((0,0), (w,h))
Jeraldinejeralee answered 18/9, 2020 at 14:12 Comment(0)
J
2

We can make use of the Functor and Applicative instance of a list to generate this with:

allCoords :: (Num a, Enum a, Num b, Enum b) => a -> b -> [(a, b)]
allCoords h w = (,) <$> [0 .. h-1] <*> [0 .. w-1]

Here (,) <$> [0 .. h-1] will produce a list of functions b -> (a, b) where the first item of the tuple is already filled in. With the TupleSections enabled, this list is equivalent to [(0,), (1,), …, (w-1,)].

Then the (<*>) function will take a function from this list, and for each such function call it on each value in the list [0 .. w-1], thus constructing 2-tuples.

For example:

Prelude> allCoords 3 4
[(0,0),(0,1),(0,2),(0,3),(1,0),(1,1),(1,2),(1,3),(2,0),(2,1),(2,2),(2,3)]
Jaynes answered 18/9, 2020 at 17:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.