我正在研究Haskell中的代数类型,从工作表中进行一些练习。我做了以下练习:
- 定义代数类型Point,用于表示二维空间中的点(坐标)。
我的练习代码:
data Point = Point Float Float
deriving (Show)
- 使用Point,定义Shape数据类型的修改版本PositionedShape,除了其尺寸外,还包括形状的中心点。
以前定义的形状数据:
data Shape = Circle Float |
Rectangle Float Float
deriving (Show)
我的练习代码:
data PositionedShape = PositionedShape Shape Point
deriving (Show)
现在我的问题出在这一个:
定义一个功能:
haskell move :: PositionedShape -> Float -> Float -> PositionedShape
它通过给定的x和y距离移动形状
我的实现如下:
move :: PositionedShape -> Float -> Float -> PositionedShape
move (Shape (Point x y)) newX newY = Shape (Point newX newY)
这回复了我这个错误:
Week8.hs:103:7:错误:不在范围内:数据构造函数'Shape'失败,模块加载:无。
有人可以解释一下为什么会出现这个错误,我该如何解决呢?我对代数类型有点困惑,我尝试了很多东西,但似乎我无法得到解决方案。
您需要在数据构造函数(如Circle
和Rectangle
)上进行模式匹配,而不是像现在尝试的类型构造函数(如Shape
)。对于PositionedShape
,他们碰巧有相同的名字,虽然你完全忘记了这个匹配(事实上,除了复制之外,你根本不需要关心内部Shape
)。此外,move
意味着将形状移动给定距离,而不是将其移动到新的给定位置;
您需要使用PositionedShape
构造函数来分解PositionedShape
您已经使用了Shape
构造函数。
尝试从以下开始:
移动(PositionedShape形状(Point old_x old_y))[...]
怎么样
move (PointedShape s (Point x y)) dx dy = PointedShape s (Point (x+dx) (y+dy))