Элементы списка сетки - PullRequest
0 голосов
/ 14 мая 2011

Мне удалось добиться некоторого прогресса в этой части моего задания, но я приложил часть кода ниже, что я сделал:

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 = любой Int, как показано ниже (с инвертированным элементом xth) - ghci.

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

Однако все отклеивается, когда я пытаюсь работать с несколькими списками, такими как этот, или выбираю определенный список в списке, чтобы обновить элемент xth:

*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.

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 14 мая 2011
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 s.

Вторая строка теперь означает «если вы хотите обновить 0-ю строку этой сетки, а затем обновить первую строку», последняя строка должна означать «если вы хотите обновить y-ю строкуэтой сетки, затем оставьте первый как есть, и рекурсивно обновите остальные строки "(конечно, y должен быть соответствующим образом изменен в рекурсивном вызове).

0 голосов
/ 17 мая 2011

Вот решение.Подумав немного, я предложил следующее и заполнил последнюю строчку из вышеприведенного «шаблона»:

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