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 コードは機能しません。なんで?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
4

3 に答える 3

2

あなたの最後の行は、Radiusオブジェクトを構築し、それを累乗しています。の累乗演算子を定義していないためRadius、機能しません。コンストラクター呼び出しを削除します。

surface (Circle _ (Radius r)) = pi * r ^ 2
于 2012-07-20T06:48:48.357 に答える
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 に答える
1

2つの修正があります。1 つは、最初に記述したコード スニペットとまったく同じです。実際の計算ビットでは、a のFloat代わりに aを使用します。Radius

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

もう 1 つは、次のタイプを調べることです(^)

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

...そして forRadius r ^ 2が機能するためには、 instance が必要であることに注意してNum Radiusください。また、結果は type の値Radius(not 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 に答える