2011-05-14 63 views
0

我設法使我的任務,這部分一些進展,但附上下面的代碼我已經做的一部分:單欄元素

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如下所示(與倒數第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 

我似乎無法'genralise'這個函數的一個公式。

我也必須遵循此類型的約定:

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

如果定義'這可能是更清楚你數據網格= [行]',其等同於'Grid Grid = [[State]]' – 2011-05-14 18:09:27

回答

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只是一個名單。

第二行現在意味着「如果你想更新這個網格的第0行,然後更新第一行」,最後一行應該是「如果你想更新這個網格的第y行,則離開第一個是原樣,並遞歸更新其餘行「(當然,在遞歸調用中y必須相應地改變)。

+0

好的!我想到了! – maclunian 2011-05-17 00:18:09

0

這是解決方案。一些思考後,我出來用下面和填充上述「模式」的最後一行:

​​