Oop 一个简单的面向对象类&x27;点';在哈斯克尔
嗯,我确实意识到我对哈斯克尔感到困惑,这是我第一次和它共度周末 我只是想知道下面的OO类设计是否是Point2D 应使用Haskell编写,如下所示:Oop 一个简单的面向对象类&x27;点';在哈斯克尔,oop,haskell,Oop,Haskell,嗯,我确实意识到我对哈斯克尔感到困惑,这是我第一次和它共度周末 我只是想知道下面的OO类设计是否是Point2D 应使用Haskell编写,如下所示: import Prelude hiding ( sum ) -- ............................................................... -- "class type" : types belonging to this family of types --
import Prelude hiding ( sum )
-- ...............................................................
-- "class type" : types belonging to this family of types
-- must implement distance and sum functions
-- ...............................................................
class PointFamily p where
-- p is a type of this family, not a point
distance :: p -> p -> Float -- takes two things of type p and returns a Real
sum :: p -> p -> p -- takes two things of type p and returns a p thing
-- ...............................................................
-- data type: Point2D
-- a new type with x and y coordinates
-- ...............................................................
data Point2D = Point2D { x :: Float , y :: Float }
deriving (Show) -- it is "showable/printable"
-- ...............................................................
-- Point2D belongs to PointFamily, so let's say it and
-- how to compute distance and sum for this type
-- ...............................................................
instance PointFamily Point2D where
-- ............................................................-
distance p1 p2 = sqrt (dx*dx + dy*dy)
where
dx = (x p1) - (x p2)
dy = (y p1) - (y p2)
-- ............................................................-
sum p1 p2 = Point2D { x = (x p1)+(x p2), y = (y p1)+(y p2) }
-- ...............................................................
-- global constant
-- ...............................................................
origin = Point2D 0.0 0.0
-- ...............................................................
-- main
-- ...............................................................
main = do
putStrLn "Hello"
print b
print $ distance origin b
print $ sum b b
where
b = Point2D 3.0 4.0
是的,我知道我不应该在Haskell中尝试“思考OOP”,但是。。。好吧,1)这将需要很长时间,2)在实践中,我想你会发现一些面向对象的设计需要在Haskell中重写。首先:的确
但是你的代码根本不是OOP。如果您开始尝试虚拟继承等,那将是OO,但在本例中,OO实现更像是明显的Haskell实现
只是,应该强调的是,类型类
PointFamily
与数据类型Point2D
没有任何特定的1:1关系,就像它们在OO类中捆绑一样。在实践中,您可以为任何可能有效的类型创建该类的实例。毫不奇怪,所有这些以前都做过;PointFamily
最广泛的等价物是。这更一般,但原则上也有相同的目的。为了说明LeftRoundound关于不需要考虑OO的观点,我冒昧地删除了typeclass,以展示代码的简单性。如果您当前需要编写未经修改的二维和三维点代码,请不要投票支持此功能。但我怀疑你现在真正需要的是一个2D点,这段代码做得很好。这是基于“你不会需要它”的原则。如果后来发现您确实需要它,有几种方法可以介绍它
我还在x和y字段上添加了bang模式,因为典型的2D应用程序通常希望这些字段严格
import Prelude hiding ( sum )
data Point2D = Point2D { x :: !Float , y :: !Float }
deriving (Read,Show,Eq)
distance :: Point2D -> Point2D -> Float -- takes two things of type p and returns a Real
distance p1 p2 = sqrt (dx*dx + dy*dy)
where
dx = (x p1) - (x p2)
dy = (y p1) - (y p2)
sum :: Point2D -> Point2D -> Point2D -- takes two things of type p and returns a p thing
sum p1 p2 = Point2D { x = (x p1)+(x p2), y = (y p1)+(y p2) }
origin = Point2D 0.0 0.0
main = do
putStrLn "Hello"
print b
print $ distance origin b
print $ sum b b
where
b = Point2D 3.0 4.0
谢谢关于PointFamily,是的,我认为PointFamily中可能还有其他类型,例如,很明显,Point3D。只是好奇什么!浮动意味着。@cibercitizen1:它使数据字段变得严格,本质上是一种优化。(通常,Haskell值一开始都是惰性Thunk值,以后可能只能计算为具体值。当计算整个
点时,输入!
会强制执行此操作。)-顺便说一句,除了有时在非固定数组中。@GarethR你确定类型签名中的p
不太一般吗?@Ingo,谢谢你的提醒。我将它们替换为Point2D
。添加点的想法在数学上很独特。