L01*_*man 10 haskell types function
我有这些数据类型:
data PointPlus = PointPlus
{ coords :: Point
, velocity :: Vector
} deriving (Eq)
data BodyGeo = BodyGeo
{ pointPlus :: PointPlus
, size :: Point
} deriving (Eq)
data Body = Body
{ geo :: BodyGeo
, pict :: Color
} deriving (Eq)
Run Code Online (Sandbox Code Playgroud)
它是我游戏中角色,敌人,物体等的基本数据类型(好吧,我现在只有两个矩形作为玩家和地面:p).
当一个键,字符通过改变它来向右,向左或跳跃velocity
.移动是通过添加velocity
到coords
.目前,它的编写如下:
move (PointPlus (x, y) (xi, yi)) = PointPlus (x + xi, y + yi) (xi, yi)
Run Code Online (Sandbox Code Playgroud)
我只是接受了PointPlus
我的一部分,Body
而不是全部Body
,否则它将是:
move (Body (BodyGeo (PointPlus (x, y) (xi, yi)) wh) col) = (Body (BodyGeo (PointPlus (x + xi, y + yi) (xi, yi)) wh) col)
Run Code Online (Sandbox Code Playgroud)
第一版move
更好吗?无论如何,如果move
只是改变PointPlus
,必须有另一个函数在新的内部调用它Body
.我解释说:有一个函数update
被调用来更新游戏状态; 它传递给当前的游戏状态,Body
现在只有一个,并返回更新的Body
.
update (Body (BodyGeo (PointPlus xy (xi, yi)) wh) pict) = (Body (BodyGeo (move (PointPlus xy (xi, yi))) wh) pict)
Run Code Online (Sandbox Code Playgroud)
这让我感到痒痒.Body
除了之外,一切都保持不变PointPlus
.有没有办法避免手工完成"重建"?像:
update body = backInBody $ move $ pointPlus body
Run Code Online (Sandbox Code Playgroud)
backInBody
当然,无需定义.
Tik*_*vis 14
你正在寻找"镜头".镜片有几种不同的包装; 这是对它们的一个很好的总结.
我的理解是,a
某个字段的数据类型上的镜头b
提供了两种操作:获取值的b
方法和获取a
具有不同值的新方法b
.因此,您只需使用镜头即可深度嵌套PointPlus
.
镜头包提供了与镜头一起使用的有用功能以及自动生成镜头的方法(使用模板Haskell),这可能非常方便.
我认为他们值得研究您的项目,特别是因为您的数据类型结构可能会遇到类似的嵌套问题.