在“制作我们自己的类型和类型类”中,他们给出了以下代码:
data Point = Point Float Float deriving (Show)
data Shape = Circle Point Float | Rectangle Point Point deriving (Show)
surface :: Shape -> Float
surface (Circle _ r) = pi * r ^ 2
surface (Rectangle (Point x1 y1) (Point x2 y2)) = (abs $ x2 - x1) * (abs $ y2 - y1)
nudge :: Shape -> Float -> Float -> Shape
nudge (Circle (Point x y) r) a b = Circle (Point (x+a) (y+b)) r
nudge (Rectangle (Point x1 y1) (Point x2 y2)) a b = Rectangle (Point (x1+a) (y1+b)) (Point (x2+a) (y2+b))
main = do
print (surface (Circle (Point 0 0) 24))
print (nudge (Circle (Point 34 34) 10) 5 10)
就目前而言,针对构造函数的模式匹配在这一点上变得非常混乱
nudge (Rectangle (Point x1 y1) (Point x2 y2)) a b = ....
如果我们将 Shape 类型定义为:
data Shape = Circle Point Float | Rectangle Float Float Float Float deriving (Show)
然后,即使我们对类型的性质失去了一点清晰,模式匹配看起来也不那么混乱,如下所示:
data Point = Point Float Float deriving (Show)
data Shape = Circle Point Float | Rectangle Float Float Float Float deriving (Show)
surface :: Shape -> Float
surface (Circle _ r) = pi * r ^ 2
surface (Rectangle x1 y1 x2 y2) = (abs $ x2 - x1) * (abs $ y2 - y1)
nudge :: Shape -> Float -> Float -> Shape
nudge (Circle (Point x y) r) a b = Circle (Point (x+a) (y+b)) r
nudge (Rectangle x1 y1 x2 y2) a b = Rectangle (x1+a) (y1+b) (x2+a) (y2+b)
main = do
print (surface (Circle (Point 0 0) 24))
print (nudge (Circle (Point 34 34) 10) 5 10)
我的问题是是否可以同时拥有
Rectangle Point Point
和
Rectangle Float Float Float Float
在同一段代码中(即一种“重载”值构造函数),以便我们可以执行以下操作:
...
surface (Rectangle (Point x1 y1) (Point x2 y2)) = (abs $ x2 - x1) * (abs $ y2 - y1)
...
nudge (Rectangle x1 y1 x2 y2) a b = Rectangle (x1+a) (y1+b) (x2+a) (y2+b)
其中“...”表示与上面代码中的相同。还有其他技巧可以使符号在“轻推(矩形......”点上更紧凑吗?谢谢