Возвращает список всех возможных координат в сетке такой ширины и высоты

#haskell #cartesian-product #cartesian-coordinates

#haskell #декартово произведение #декартовы координаты

Вопрос:

Итак, я пишу функцию allCoords , которая возвращает список всех возможных координат в сетке ширины w и высоты h width и height должна быть неотрицательными целыми числами, чтобы вернуть разумный результат.

Пример: allCoords 3 2 должен возвращать [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)]

Это все, что у меня есть на данный момент, но я не знаю, как даже начать писать функцию

 type GridCoord = (Int, Int)

allCoords :: Int -> Int -> [GridCoord]
  

Комментарии:

1. изменения не должны приводить к аннулированию существующих ответов. если у вас уже «есть это», то в чем будет вопрос?

Ответ №1:

Вы могли бы сделать это, используя понимание списка.

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

Даст список в вашем примере.

Затем ваша функция должна быть определена как:

 type GridCoord = (Int, Int)

allCoords :: Int -> Int -> [GridCoord]
allCoords height width = [ (x,y) | x <- [0..width-1], y <- [0..height-1] ]
  

Ответ №2:

range Функция делает это.

 import Data.Ix
allCoords h w = range ((0,0), (w,h))
  

Ответ №3:

Мы можем использовать Functor и Applicative экземпляр списка для генерации этого с помощью:

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

Здесь (,) <$> [0 .. h-1] будет создан список функций b -> (a, b) , в которых первый элемент кортежа уже заполнен. При TupleSection включенном s этот список эквивалентен [(0,), (1,), …, (w-1,)] .

Затем (<*>) функция будет принимать функцию из этого списка и для каждой такой функции вызывать ее для каждого значения в списке [0 .. w-1] , создавая таким образом 2-кортежа.

Например:

 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)]