kei*_*thb 4 haskell visibility module typeclass
为了掌握更好的类型类(从几乎从形式开始)我开始使用面积计算来建模二维形状,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
等等其他形状.
这很好,但我想到尝试这个:
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
Run Code Online (Sandbox Code Playgroud)
等等也没关系.以信息隐藏为目标,我将模块声明更改为如下所示:
module TwoDShapes (TwoDShape, area, aCircle, anEllipse, aRectangle, aTriangle)
Run Code Online (Sandbox Code Playgroud)
并且稍微令我惊讶的是1)工作和2)在ghci aCircle 评估TwoDShapeParams 1.0 1.0 3.1415927哪个是真的但我不明白该类型TwoDShapeParams在模块外是如何可见的.我不确定我在期待什么,但不是这个.
我真正喜欢的是类型类,它的方法和"智能构造函数"在模块外部可见而没有别的.可以这样做吗?
尽管TwoDShapes隐藏了表示,但您已Show为其派生了一个实例,它允许将任意类型的值TwoDShapes转换为a String,因此这是信息泄漏的来源.真正的抽象类型不应该定义Show实例,或者实际上是一个Data类似地公开有关表示的信息的实例.有一种方法可以将类型转换为a String,只要它与String表示无关(请参阅Show实例Data.Map.Map以及Data.Array.Array此示例).
请注意,模块系统正在完成其工作:您仍然无法引用TwoDShapes定义它的模块之外的构造函数.
| 归档时间: |
|
| 查看次数: |
723 次 |
| 最近记录: |