我正在尝试使用 haskell 模拟跳棋游戏。我得到了一个名为 checkersState 的 4 元组,我想用几个不同的函数来操作它。到目前为止,我有一个函数 oneMove,它接收来自 checkerState 的输入,并应返回修改后的数据的元组:
输入元组:
(
3600,
"",
[
"----------",
"------r---",
"----------",
"----------",
"---r-r----",
"------r---",
"---w---w-w",
"----------",
"----------",
"------w---"
],
(
49
,
43
)
)
到目前为止,我有类似于下面定义我的函数的内容,但不确定如何访问元组 checkerState 中的各个成员。此方法将花费时间、捕获棋子数组、棋盘和棋子来进行制作,并返回时间、捕获棋子数组和棋盘。目前,我想根据板的状态修改元组中的时间(INT):
onemove :: (Int,[Char],[[Char]],(Int,Int)) -> (Int,[Char],[[Char]])
提前致谢!
最佳答案
您可以使用模式匹配来提取元素,进行任何需要的更改,然后将它们打包回元组中。例如,如果您想增加第一个值,您可以:
onemove (a,b,c,d) = (a + 1,b,c,d)
如果您发现自己经常这样做,您可能会重新考虑使用元组并改用数据类型:
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)
然后您可以使用更方便的语法更新它:
onemove state = state { time = time state + 1 }
如果您想坚持使用元组并且您碰巧正在使用 lenses ,还有另一种简单的方法来更新元组:
onemove = over _1 (+1)
或者,如果您使用镜头和您自己的数据类型(使用像所提供的那样适当定义的访问器),您可以执行类似的操作:
_time :: Lens' CheckersState Int
_time f state = (\newTime -> state { time = newTime }) <$> f (time state)
onemove = over _time (+1)
所以有很多奇特的方法可以做到这一点。但最通用的方法是使用模式匹配。
关于Haskell——操作元组中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25195732/