为了把握更好的类型类(首发几乎从零开始的形式),我在模型2-d的形状一展身手与面积计算,像这样:类型类和模块如何交互?
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
如何在模块外部可见。我不确定我期待的是什么,但不是这个。
我真的很喜欢typeclass,它的方法和“聪明的构造函数”是可见的模块外,没有别的。可以这样做吗?
我感到惊讶(我没有在这台计算机上安装Haskell编译器,所以无法检查会发生什么)是,'aCircle'可以在所有非导出类型'TwoDShapeParams' (不是它的值构造函数)出现在它的类型中。 – 2010-07-12 12:06:26
您编写了'Module TwoDShapes(TwoDShape,...',它输出* type *'TwoDShape',但不是它的表示。但是,即使你没有导出类型,你仍然可以导出一个类型为“TwoDShape”的函数,否则你就无法在其他地方引用'TwoDShape'。 Haskell模块系统控制标识符的可见性,这就是它的全部功能。 – 2010-07-12 13:17:10
我不是问题的作者:) – 2010-07-12 13:37:38