让一个模块来抽象Area
操作(不好的定义)
class Area someShapeType where
area :: someShapeType -> Float
-- module utilities
sumAreas :: Area someShapeType => [someShapeType]
sumAreas = sum . map area
让后验显式形状类型模块(良好或可接受的定义)
data Point = Point Float Float
data Circle = Circle Point Float
instance Surface Circle where
surface (Circle _ r) = 2 * pi * r
data Rectangle = Rectangle Point Point
instance Surface Rectangle where
surface (Rectangle (Point x1 y1) (Point x2 y2)) = abs $ (x2 - x1) * (y2 - y1)
放一些数据
c1 = Circle (Point 0 0) 1
r1 = Rectangle (Point 0 0) (Point 1 1)
然后,尝试使用
totalArea = sumAreas [c1, r1]
[c1, r1]
类型必须扩展为[Circle]
or [Rectangle]
!(并且无效)
我可以使用这样forall
的额外data
类型
data Shape = forall a . Surface a => Shape a
sumSurfaces :: [Shape] -> Float
sumSurfaces = sum . map (\(Shape x) -> surface x)
然后,下一个代码成功运行
sumSurfaces [Shape c1, Shape r1]
但我认为,data Shape
andShape
构造函数(on[Shape c1, ...]
和 lambda 参数)的使用是丑陋的(我的第一个 [和坏的] 方式很漂亮)。
做“Haskell中的异构多态性”的正确方法是什么?
非常感谢您的宝贵时间!