我已经设法在我的任务的这一部分取得了一些进展,但已经附上了我所做的部分代码:
module Grid where
data State = On | Off deriving (Eq, Show)
next :: State -> State
next On = Off
next Off = On
type Row = [State]
type Grid = [[State]]
type Point = (Int,Int)
initialRow :: Int -> Row
initialRow w = replicate w Off
updateRow :: Row -> Int -> Row
updateRow (r:rs) x
| x==0 = next r:rs
| otherwise = r : (updateRow rs (x-1))
update :: Grid -> Point -> Grid
update [[]] (x,y) = [[]]
update [(g:gs)] (x,y) = [(updateRow (g:gs) x)]
正如上面的最后一行所示,我已经设法让更新在x = any Int时工作,如下所示(第x个元素被反转) - ghci。
*Grid> update [[Off,Off,Off,Off]] (2,0)
[[Off,Off,On,Off]]
*Grid>
当我尝试使用多个这样的列表,或者在列表中选择某个列表来更新第x个元素时,这一切都会失败:
*Grid> update [[Off,Off,Off,Off],[Off,Off,Off,Off]] (2,0)
*** Exception: Grid.hs:(24,0)-(25,47): Non-exhaustive patterns in function update
我似乎无法在这个函数中“推广”一个公式。
我也必须遵循这种类型约定:
updateRow :: Grid -> Point -> Grid
基本上,我想做的是从这样的事情更新......
[[Off,Off,Off,Off],
[Off,Off,Off,Off],
[Off,Off,Off,Off],
[Off,Off Off,Off]]
到此:
[[Off,Off,Off,Off],
[Off,Off,**On**,Off],
[Off,Off,Off,Off],
[Off,Off Off,Off]]
其中'x'是元素的值,'y'是列表IYGWIM中列表的值。
提前致谢。
答案 0 :(得分:2)
update :: Grid -> Point -> Grid
update [[]] (x,y) = [[]]
这将检查包含空列表的列表。
update [(g:gs)] (x,y) = [(updateRow (g:gs) x)]
这将检查包含一个列表的列表,后者包含至少一个元素(绑定到变量g)。
您想要检查包含多个列表的列表。
模式应如下所示:
update :: Grid -> Point -> Grid
update [[]] (x, y) = [[]]
update (row:rows) (x, 0) = updateRow row x : rows
update (row:rows) (x,y) = -- I'll let you fill this, notice the 0 on the previous line
请记住,Grid
只是Row
的列表。
第二行现在意味着“如果你想更新这个网格的第0行,然后更新第一行”,最后一行应该是“如果你想更新这个网格的第y行,那么就留下第一行一个原样,并递归更新其余的行“(当然,y必须在递归调用中相应地更改)。
答案 1 :(得分:0)
这是解决方案。经过一番思考后,我出现了以下内容并填写了上述“模式”的最后一行:
...
update (g:gs) (x,y) = g : update gs (x,(y-1))