Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 一个简单的面向对象类&x27;点';在哈斯克尔_Oop_Haskell - Fatal编程技术网

Oop 一个简单的面向对象类&x27;点';在哈斯克尔

Oop 一个简单的面向对象类&x27;点';在哈斯克尔,oop,haskell,Oop,Haskell,嗯,我确实意识到我对哈斯克尔感到困惑,这是我第一次和它共度周末 我只是想知道下面的OO类设计是否是Point2D 应使用Haskell编写,如下所示: import Prelude hiding ( sum ) -- ............................................................... -- "class type" : types belonging to this family of types --

嗯,我确实意识到我对哈斯克尔感到困惑,这是我第一次和它共度周末

我只是想知道下面的OO类设计是否是Point2D

应使用Haskell编写,如下所示:

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
。添加点的想法在数学上很独特。