开发者

List Grid Elements

I have managed to make some progress in this part of my assignment but have attached part of the code below that I have made:

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)       =   [[]]
updat开发者_C百科e [(g:gs)] (x,y)   =   [(updateRow (g:gs) x)]

As shown in the last line just above, I have managed to get update to work for when x = any Int as shown below (with the xth element inverted) - ghci.

*Grid> update [[Off,Off,Off,Off]] (2,0)
[[Off,Off,On,Off]]
*Grid> 

It all comes unstuck however when I try working with multiple lists such as this, or select a certain list within the list to update the xth element:

*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

I can't seem to 'genralise' a formula in this function.

I also MUST follow THIS type convention:

updateRow :: Grid -> Point -> Grid

Basically, what I would like to do is update from something like this...

[[Off,Off,Off,Off],
 [Off,Off,Off,Off],
 [Off,Off,Off,Off],
 [Off,Off Off,Off]]

to this:

[[Off,Off,Off,Off],
 [Off,Off,**On**,Off],
 [Off,Off,Off,Off],
 [Off,Off Off,Off]]

where 'x' is the value of the element and 'y' is the value of the list within the list IYGWIM.

Thanks in advance.


update :: Grid -> Point -> Grid
update [[]] (x,y)       =   [[]]

This checks for a list that contains the empty list.

update [(g:gs)] (x,y)   =   [(updateRow (g:gs) x)]

This checks for a list that contains one list, the latter containing at least one element (bound to the variable g).

You want to check for a list that contains multiple lists.

The pattern should look like:

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

Remember a Grid is just a list of Rows.

The second line now means "if you want to update the 0th line of this grid, then update the first row", the last line should mean "if you want to update the yth line of this grid, then leave the first one as is, and recursively update the rest of the rows" (of course, y must be changed accordingly in the recursive call).


Here is the solution. After some thought, I came out with the following and filled the final line of the above 'pattern':

...
update        (g:gs)  (x,y) =  g : update gs (x,(y-1))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜