Haskell中的类型错误

Haskell中的类型错误,haskell,type-conversion,Haskell,Type Conversion,我得到以下错误: exercise-2-2.hs:15:49: Couldn't match expected type `Double' with actual type `Int' In the fourth argument of `regularPolygonHelper', namely `theta' In the expression: regularPolygonHelper n s 0 theta r In an equation for `re

我得到以下错误:

exercise-2-2.hs:15:49:
    Couldn't match expected type `Double' with actual type `Int'
    In the fourth argument of `regularPolygonHelper', namely `theta'
    In the expression: regularPolygonHelper n s 0 theta r
    In an equation for `regularPolygon':
        regularPolygon n s
          = regularPolygonHelper n s 0 theta r
          where
              r = s / 2.0 * (sin (pi / n))
              theta = (2.0 * pi) / n
在以下代码中:

data Shape = Rectangle Side Side
           | Ellipse Radius Radius
           | RTTriangle Side Side
           | Polygon [Vertex]
    deriving Show

type Radius = Float
type Side   = Float
type Vertex = (Float, Float)

square s = Rectangle s s
circle r = Ellipse r r

regularPolygon :: Int -> Side -> Shape
regularPolygon n s = regularPolygonHelper n s 0 theta r
    where r     = s / 2.0 * (sin (pi / n))
          theta = (2.0 * pi) / n

regularPolygonHelper :: Int -> Side -> Int -> Double -> Double -> Shape
regularPolygonHelper 0 s i theta r = Polygon []
regularPolygonHelper n s i theta r = 
    (r * cos (i * theta), r * sin (i * theta)) : 
        (regularPolygonHelper (n - 1) s (i + 1) theta r)

为什么会这样?
(2.0*pi)/n
不是双精度的吗?

Haskell在不同的数字类型之间没有自动转换。你必须用手来做这件事。在您的情况下,
(2.0*pi)/from integral n
就可以了。(您必须在所有其他需要强制转换的地方添加此选项)原因是,隐式转换将使类型推断更加困难,因此,使用类型推断比自动转换更好。

最好不要将类型混合得太多 以下是迄今为止编译的版本:


data Shape = Rectangle Side Side
           | Ellipse Radius Radius
           | RTTriangle Side Side
           | Polygon [Vertex]
    deriving Show

type Radius = Double
type Side   = Double
type Vertex = (Double, Double)

square s = Rectangle s s
circle r = Ellipse r r

regularPolygon :: Int -> Side -> Shape
regularPolygon n s = regularPolygonHelper n s 0 theta r
    where r     = s / 2.0 * (sin (pi / fromIntegral n))
          theta = (2.0 * pi) / fromIntegral n

regularPolygonHelper :: Int -> Side -> Int -> Double -> Double -> Shape
regularPolygonHelper 0 s i theta r = Polygon []
regularPolygonHelper n s i theta r = 
    let Polygon rPoly = regularPolygonHelper (n - 1) s (i + 1) theta r in
    Polygon ((r * cos (fromIntegral i * theta), r * sin (fromIntegral i * theta)) : rPoly)


奇怪-尝试过这个,但这不是唯一的问题,在我的情况下也不起作用。。。但是如果这是正确的答案。。。自动转换也可能导致精度损失,这可能是另一个需要追踪的头痛问题。总的来说,我认为在混合数字类型时显式的比隐式的好。你们有没有检查代码中的建议更改?它能工作吗?它能产生正确的输出吗(例如一个简单的正方形)?regularPolygonHelper仍然存在问题tell@CKoenig你必须在所有其他你想有演员阵容的地方加上这个。。。你真的读过我的答案吗?我觉得这个结果不正确,但我认为问题不在于我的改变。。。虽然不确定,但我很累。。。Sorry我不会对边数使用
Double
。它会导致出现错误,例如通过
0.5
,这将导致跳过
0
基本情况。类似地,我可能会为负数添加一个
错误
案例。真的-反正只是一个快速破解,因为我认为算法不正确。但正如我提到的:from积分能解决这个问题吗?我不这么认为。你不需要某种Int->Double(Float)吗?我有点惭愧,但我不知道如何在haskell中做到这一点:(看看
from Integral::(Integral a,Num b)=>a->b
。它可以从任何整数类型(例如
Int
)转换为任何数字类型(例如
Double
).读了一点之后,它应该是从Integral开始的-但是为什么我的GHCi要对我施加压力…我一定很困了..抱歉明天会处理它…请注意您上次在regularPolygonHelper中调用的问题-您正在将顶点预加到形状上-但是您想将顶点预加到顶点列表并返回“Polygon newList”