让一个模块来抽象Area
操作(错误的定义)
class Area someShapeType where
area :: someShapeType -> Float
-- module utilities
sumAreas :: Area someShapeType => [someShapeType]
sumAreas = sum . map area
Let a 后验的显式形状类型模块(良好或可接受的定义)
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]
the [c1, r1]
类型必须扩展为[Circle]
or [Rectangle]
! (并且无效)
我可以使用forall
and额外的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
and Shape
构造函数(在[Shape c1, ...]
和 lambda 参数)是丑陋的(我的第一个[也是坏]方法很漂亮)。
正确的做法是什么“Haskell 中的异构多态性”?
非常感谢您的宝贵时间!