【发布时间】:2018-10-21 03:10:57
【问题描述】:
我有一个类Movable 和多个数据类型实例化这个类。我想为所有这些类创建一个通用移动函数,如下所示,但显然我的记录语法不正确,因为我收到以下错误:
src\Controller.hs:24:13: error:
* `position' is not a record selector
* In the expression: o {position = (x', y')}
In an equation for `move':
move o
= o {position = (x', y')}
where
(x, y) = position o
(vx, vy) = velocity o
x' = x + vx
y' = y + vy
|
24 | move o = o {position = (x', y')}
| ^^^^^^^^
我尝试应用此StackOverflow answer,但没有成功。 如何解决这个问题?或者除了使用记录语法还有其他方法可以解决这个问题吗? 在这里你可以看到我的代码:
type Position = (Float, Float)
type Velocity = (Float, Float)
class Movable m where
position :: m -> Position
velocity :: m -> Velocity
data Player = Player {
playerBulletType :: Bullet,
playerHealth :: Health,
playerMaxVelocity :: MaxVelocity,
playerVelocity :: Velocity,
playerPosition :: Position,
playerSprite :: Sprite
}
instance Movable Player where
position = playerPosition
velocity = playerVelocity
move :: Movable o => o -> o
move o = o {position = (x', y')}
where (x, y) = position o
(vx, vy) = velocity o
x' = x + vx
y' = y + vy
【问题讨论】:
-
好吧,您没有使用字段
position定义记录类型,所以这是预期的行为。您在这里将position定义为某种“getter”,因此即使您可以以某种方式调用这样的“setter”,也没有多大意义。 -
@WillemVanOnsem 不明白,我说我定义了具有 Movable 实例的类(正如您现在可以在问题代码中看到的那样)。
-
Haskell 中的
class更像是其他编程语言中的“接口”。您在此处定义如下函数:position :: m -> Position,因此它将Movable“转换”为Position,而不是相反。 -
但是这个问题看起来不像我链接的问题吗? @willemVanOnsem
-
你可以定义一个像
setPosition -> Position -> m -> m这样的“setter”,然后调用“setter”。