我定义了两种数据类型:Point和Curve。 Point的坐标有两个双精度,曲线有一个起点和一个表示曲线其余部分的点列表。我需要创建一个函数来创建这个曲线给定一个起点和一个点列表,但我不能理解我应该如何将一个元素添加到曲线内的点列表中。 这是我的代码:
data Point = Point Double Double deriving (Eq, Show)
point :: (Double, Double) -> Point
point (x, y) = Point x y
data Curve = Curve Point [Point] deriving (Eq, Show)
curve :: Point -> [Point] -> Curve
curve x [] = Curve x []
curve x [y] = Curve x [y]
curve x (y:ys) = curve x (y:ys)
我很确定我的递归最终是错误的。那么你能给我一些关于如何在列表中添加一个点的指导原则吗?
感谢
答案 0 :(得分:6)
myCurve = Curve (Point 2 2) [Point 3 3, Point 4 4, Point 5 5]
等等,你说什么?实际上,Curve
已经是您想要的功能了。它既是类型构造函数(数据定义中的左侧),也是值构造函数(右侧)。
如果您使用ghci探测Curve
,您会发现......
Prelude> :t Curve Curve :: Point -> [Point] -> Curve
Point
也是如此。换句话说,您的整个代码如下所示:
编辑:价值构建者的超小型入门。data Point = Point Double Double deriving (Eq, Show) data Curve = Point [Point] deriving (Eq, Show)
创建新数据类型时,会自动创建一个值构造函数,该构造函数是一个创建新类型值的函数。它在你的例子中并不完全清楚,因为类型和值构造函数具有相同的名称,这在Haskell中是允许的,因为一个存在于类型级别而另一个存在于值级别中。让我们试着让它更明显一点:
data MyIntType = MakeIntType Int
现在,MakeIntType
是一个函数,它接受一个参数Int
,并创建一个MyIntType
类型的值。我们来看看ghci:
Prelude> :t MakeIntType
MakeIntType :: Int -> MyIntType
现在,我们可以编写一个相同的功能,就像你提出的那样:
makeIntType :: Int -> MyIntType
makeIntType x = MakeIntType x
或者,删除显式点(参数):
makeIntType = MakeIntType
这两个等式表明我们已经重复工作。 makeIntType和MakeIntType之间没有功能差异。它们是完全等价的,因为你总是得到价值构造函数"免费," makeIntType是已经存在的东西的完全多余的别名。
我希望稍微澄清一下。
编辑2:根据现有的<{p>>创建新的修改后的Curve
addPointToStartOfCurve p (Curve p' ps) = Curve p (p':ps)
在这里,我们通过将现有曲线的第一个元素推到点列表并添加新的起点来从现有曲线创建新曲线。另一种变体会在现有曲线的末尾添加一个点。
addPointToEndOfCurve p (Curve p' ps) = Curve p' (ps ++ [p])
请注意,由于不变性,原始曲线没有改变,我们只是生成新值。