所以我正在编写一个函数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]
您可以使用列表理解来实现这一点。
[ (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] ]
range
函数可以做到这一点。
import Data.Ix
allCoords h w = range ((0,0), (w,h))
我们可以使用列表的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
后,该列表等效于[(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)]