function - Haskell:函数应该接收的类型为 "how much"?并避免完整的 "reconstruction"

标签 function haskell types

我有这些数据类型:

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)

它是我游戏中角色、敌人、物体等的基本数据类型(好吧,我现在只有两个矩形作为玩家和地面:p)。

当一个键时,字符通过改变它的velocity来向右、向左或跳跃。 .通过添加 velocity 来完成移动。到coords .目前,它的编写如下:
move (PointPlus (x, y) (xi, yi)) = PointPlus (x + xi, y + yi) (xi, yi)

我只是服用PointPlus我的一部分Body而不是整个 Body ,否则它将是:
move (Body (BodyGeo (PointPlus (x, y) (xi, yi)) wh) col) = (Body (BodyGeo (PointPlus (x + xi, y + yi) (xi, yi)) wh) col)

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)

这让我很痒。 Body 内的一切都保持不变除了 PointPlus .有没有办法手动避免这种完全的“重建”?像:
update body = backInBody $ move $ pointPlus body

无需定义backInBody , 当然。

最佳答案

您正在寻找“镜头”。镜头有几种不同的包装; here是对它们的一个很好的总结。

我的理解是数据类型 a 的镜头对于某些领域b提供两种操作:一种获取b的值的方法以及获得新 a 的方法具有不同的值 b .因此,您只需使用镜头来处理深度嵌套的 PointPlus .

镜头包提供了使用镜头的有用功能以及自动生成镜头的方法(使用模板 Haskell),这非常方便。

我认为它们值得为您的项目研究,特别是因为由于数据类型的结构,您可能会在其他地方遇到类似的嵌套问题。

关于function - Haskell:函数应该接收的类型为 "how much"?并避免完整的 "reconstruction",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10967832/

相关文章:

c# - 在 C# 中使用 byte/short 等的任何理由?

C# 等效于 Swift typealias

c++ - C++ std::string 中是否有任何函数可以计算两个字符串的相同起始字符总数或任何最佳方法

具有跨多行参数的Javascript函数

haskell - seq 函数和严格性

.net - .NET Framework 4.0中的类型差异

php - 使用 PHP 内置 ltrim() 删除单个字符

javascript - 通过 JSON 传递 JavaScript 函数

haskell - 是否可以仅使用 Applicative 实现 MaybeT?

haskell - 为什么每个 haskell 类型都被提升(即被 _|_ 占用)?