0

下面的 Haskell 代码运行良好。

data Point = Point Float Float deriving (Show)  
data Shape = Circle Point Float  
surface :: Shape -> Float  
surface (Circle _ r) = pi * r ^ 2  

结果:

*Main> surface $ Circle (Point 0 0) 10  
314.15927  

下面的 Haskell 代码不起作用。为什么?如何正确编写表面函数ShapeCircle

data Point = Point Float Float deriving (Show)  
data Radius = Radius Float deriving (Show)

data Shape = Circle Point Radius   

surface :: Shape -> Float  
surface (Circle _ (Radius r)) = pi * (Radius r) ^ 2
4

3 回答 3

2

您的最后一行是构造一个Radius对象并将其提升为幂。由于您尚未为 定义幂运算符Radius,因此这是行不通的。删除构造函数调用:

surface (Circle _ (Radius r)) = pi * r ^ 2
于 2012-07-20T06:48:48.357 回答
1

有两个修复。一个就像您编写的第一段代码一样:在实际计算位中使用 aFloat而不是 a 。Radius

surface :: Shape -> Float
surface (Circle _ (Radius r)) = pi * r ^ 2

另一种是看类型(^)

(^) :: (Num a, Integral b) -> a -> b -> a

...并观察到Radius r ^ 2要工作,我们需要有一个实例Num Radius。此外,结果将是 type 的值Radius(不是Float),因此surface必须更改的类型签名才能匹配。简单的:

newtype Radius = Radius Float deriving (Num, Show)

surface :: Shape -> Radius -- weird looking type
surface (Circle _ r) = pi * r ^ 2
surface (Circle _ (Radius r)) = pi * Radius r ^ 2 -- equivalent
于 2012-07-20T06:51:47.383 回答
1

您可以简单地使用(,)代替Point,和Float代替Radius

您还可以将 定义Shape为一个类。所以代码将是

type Point = (Float, Float)
data Circle = Circle { center :: Point, radius :: Float }

class Shape a where
  surface :: a -> Float

instance Shape Circle where
  surface c = pi * (radius c) ** 2

这是一个可能的实现,试试吧~

于 2012-07-20T08:14:41.600 回答