下面的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代码不起作用。为什么?如何正确编写Shape
- Circle
的表面函数?
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
答案 0 :(得分:2)
你的最后一行是构建一个Radius
对象并将其提升为一个权力。由于您尚未定义Radius
的幂运算符,因此无效。删除构造函数调用:
surface (Circle _ (Radius r)) = pi * r ^ 2
答案 1 :(得分:1)
有两个修复。一个就像你写的第一段代码一样:在实际计算位中使用Float
而不是Radius
。
surface :: Shape -> Float
surface (Circle _ (Radius r)) = pi * r ^ 2
另一种是查看(^)
的类型:
(^) :: (Num a, Integral b) -> a -> b -> a
...并观察到Radius r ^ 2
工作,我们需要一个实例Num Radius
。此外,结果将是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
答案 2 :(得分: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
这是一种可能的实现方式,只需尝试一下〜