我正试图用haskell来模拟一个跳棋游戏.我得到一个名为checkersState的4元组,我想用几个不同的函数来操作.到目前为止,我有一个函数oneMove,它接收来自checkerState的输入,并应返回修改数据的元组:
输入元组:
(
3600,
"",
[
"----------",
"------r---",
"----------",
"----------",
"---r-r----",
"------r---",
"---w---w-w",
"----------",
"----------",
"------w---"
],
(
49
,
43
)
)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我有类似于下面定义我的函数的东西但不确定如何访问元组checkerState中的各个成员.这种方法需要一段时间,一系列被捕获的棋子,棋盘和移动制作,并返回一个时间,一系列被捕获的棋子和棋盘.目前,我想根据主板的状态修改元组中的时间(INT):
onemove :: (Int,[Char],[[Char]],(Int,Int)) -> (Int,[Char],[[Char]])
Run Code Online (Sandbox Code Playgroud)
提前致谢!
您可以使用模式匹配来提取元素,执行需要进行的任何更改,并将它们打包回元组.例如,如果要增加第一个值,则可以:
onemove (a,b,c,d) = (a + 1,b,c,d)
Run Code Online (Sandbox Code Playgroud)
如果你发现自己做了很多,你可能会重新考虑使用元组而不是使用数据类型:
data CheckersState = CheckersState { time :: Int -- field names are just
, steps :: [Char] -- guesses; change them
, board :: [[Char]] -- to something that
, pos :: (Int, Int) -- makes sense
} deriving (Eq, Read, Show)
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用更方便的语法更新它:
onemove state = state { time = time state + 1 }
Run Code Online (Sandbox Code Playgroud)
如果你想坚持使用元组并且碰巧使用镜头,那么还有另一种更新元组的简单方法:
onemove = over _1 (+1)
Run Code Online (Sandbox Code Playgroud)
或者,如果您使用镜头和您自己的数据类型(使用适当定义的访问器,如提供的那个),您可以执行类似的操作:
_time :: Lens' CheckersState Int
_time f state = (\newTime -> state { time = newTime }) <$> f (time state)
onemove = over _time (+1)
Run Code Online (Sandbox Code Playgroud)
所以有很多奇特的方法可以做到这一点.但最常用的方法是使用模式匹配.