モジュールに操作を抽象化させ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]
タイプは or ! に展開する必要があり[Circle]
ます[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での異種多型」を行う正しい方法は何ですか?
お時間をいただきありがとうございました!