[英]Haskell--Manipulating data within a tuple
我正在尝试使用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 }
如果要坚持使用元组,而碰巧在使用lens ,则有另一种简单的方法来更新元组:
onemove = over _1 (+1)
或者,如果您使用的是镜头和自己的数据类型(使用适当定义的访问器(如提供的访问器)),则可以执行以下操作:
_time :: Lens' CheckersState Int
_time f state = (\newTime -> state { time = newTime }) <$> f (time state)
onemove = over _time (+1)
因此,有很多不错的方法可以做到这一点。 但是最通用的方法是使用模式匹配。
正如icktoofay所说,使用元组是一种代码味道,而使用命名组件进行记录则更好。
另外,使用Char(和String)是一种代码味道。 要对其进行修复,请定义一种数据类型,该数据类型应准确描述您希望在电路板上某个单元格中看到的内容,例如data Colour = None | Red | Black
data Colour = None | Red | Black
data Colour = None | Red | Black
,但请参阅下一项。
而且,使用列表也是一种代码味道。 您实际上想要的是类似type Board = Data.Map.Map Pos Colour
或Data.Map.Map Pos (Maybe Colour')
的data Colour' = Red | Black
data Colour' = Red | Black
。
哦,而且Int也是代码的味道。 您可以定义新类型newtype Row = Row Int ; newtype Col = Col Int ; type Pos = (Row,Col)
newtype Row = Row Int ; newtype Col = Col Int ; type Pos = (Row,Col)
newtype Row = Row Int ; newtype Col = Col Int ; type Pos = (Row,Col)
。 可能为新类型deriving Num
,但尚不清楚,例如,您不想乘以行号。 也许deriving (Eq,Ord,Enum)
就足够了,使用Enum
可以得到pred
和succ
。
(啊,这个Pos
使用的是一个元组,因此它很臭吗?嗯,不可以,有时允许2个元组。)
您可以使用模式匹配将元组分解为变量。
onemove (i, c, board, (x, y)) = <do something> (i, c, board)
但是,您应该为董事会定义一个单独的数据结构,以明确您的意图。 我不知道前两个值的含义。 参见: http : //learnyouahaskell.com/making-our-own-types-and-typeclasses
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.