爲了把握更好的類型類(首發幾乎從零開始的形式),我在模型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