【发布时间】:2011-03-14 18:17:32
【问题描述】:
为了掌握更好的类型类(几乎从零开始),我尝试使用面积计算对二维形状进行建模,如下所示:
module TwoDShapes where
class TwoDShape s where
area :: s -> Float
data Circle = Circle Float deriving Show
aCircle radius | radius < 0 = error "circle radius must be non-negative"
| otherwise = Circle radius
instance TwoDShape Circle where
area (Circle radius) = pi * radius * radius
data Ellipse = Ellipse Float Float deriving Show
anEllipse axis_a axis_b | axis_a < 0 || axis_b < 0 = error "ellipse axis length must be non-negative"
| otherwise = Ellipse axis_a axis_b
instance TwoDShape Ellipse where
area (Ellipse axis_a axis_b) = pi * axis_a * axis_b
其他类型的形状依此类推。
这很好,但我突然想试试这个:
module TwoDShapes where
class TwoDShape s where
area :: s -> Float
data TwoDShapeParams = TwoDShapeParams Float Float Float deriving Show
instance TwoDShape TwoDShapeParams where
area (TwoDShapeParams length_a length_b constant) = foldl (*) 1 [length_a, length_b, constant]
aCircle radius | radius < 0 = error "circle radius must be non-negative"
| otherwise = TwoDShapeParams radius radius pi
anEllipse axis_a axis_b | axis_a < 0 || axis_b < 0 = error "ellipse axis length must be non-negative"
| otherwise = TwoDShapeParams axis_a axis_b pi
等等。这也很好。为了隐藏信息,我将模块声明更改为如下所示:
module TwoDShapes (TwoDShape, area, aCircle, anEllipse, aRectangle, aTriangle)
令我惊讶的是,这 1) 有效,2) 在 ghci aCircle 中计算为 TwoDShapeParams 1.0 1.0 3.1415927,这是真的,但我不明白 TwoDShapeParams 类型如何在模块外可见。我不确定我在期待什么,但不是这个。
我真正想要的是类型类、它的方法和“智能构造函数”在模块外部可见,除此之外别无其他。可以吗?
【问题讨论】:
标签: haskell module visibility typeclass