2011-04-04 39 views
3

我有以下Haskell代码Haskell的数学式系统的乐趣

import Data.Int 
import System.Environment 

type Coord = (Int16, Int16) 

distributePointsOverCircle :: Int16 -> Int16 -> [Coord] 
distributePointsOverCircle points radius = 
    [ (xOf point, yOf point) | point <- [1..points] ] 
    where 
    xOf x = abstract cos x 
    yOf x = abstract sin x 

    abstract :: RealFrac a => (a -> a) -> Int16 -> Int16 
    abstract f x = (radius *) . truncate . f . fromIntegral $ (angleIncrement * x) * truncate (pi/180) 
    angleIncrement = div 360 points 

main = do 
    [a,b] <- getArgs 
    print $ distributePointsOverCircle (read a) (read b) 

不管我怎么传递给distributePointsOverCircle,它始终让我然而,许多COORDS我给分,每个坐标的第一个元素是列表半径和第二个元素是零。显然这不是分数的均匀分布。

我在这里做错了什么?是否有一些类型欺骗我的数字欺骗?我试图产生的函数,写在一个命令性的伪代码将是。

distributePointsOverCircle(numberOfPoints, radius) 
    angleIncrement = 360/numberOfPoints 
    points   = [] 

    for i in 0 to (numberOfPoints -1) 
    p = Point() 
    p.x = (radius * cos((angleIncrement * i) * (PI/180))) 
    p.y = (radius * sin((angleIncrement * i) * (PI/180))) 

    points[i] = p 

    return points 

回答

2

这里是我结束了:

import Data.Int 
import System.Environment 

type Coord = (Int16, Int16) 

distributePointsOverCircle :: Int16 -> Int16 -> [Coord] 
distributePointsOverCircle points radius = 
    [ (xOf point, yOf point) | point <- [1..points] ] 
    where 
    xOf x = abstract cos x 
    yOf x = abstract sin x 
    iRadius = fromIntegral radius 
    angleIncrement = div 360 points 
    abstract f x = round . (iRadius *) . f $ angle * (pi/180) 
     where 
     angle = fromIntegral $ angleIncrement * x 

main = do 
    [a,b] <- getArgs 
    print $ distributePointsOverCircle (read a) (read b) 

如前所述,问题是你除其他事项外truncate (pi/180) == 0相乘,使之前使用截断。我也认为你的主要功能有一些错误。

+0

+1表示清晰的编码风格。我有一个主要的拼写错误,无法从我的例子中通过无线互联网传输。 – Eli 2011-04-04 22:50:47

5

它给你的列表([R,0),因为truncate (pi/180) == 0。删除truncate和代码应该正常工作。

abstract f x = (radius *) . truncate . f $ fromIntegral (angleIncrement * x) * (pi/180) 
+2

好吧,删除截断并得到一个类型错误:-)你还需要在angleIncrement中粘贴'fromIntegral'。 – sclv 2011-04-04 19:51:21

+1

还要注意'div 360 points是整数除法,对于> 360点总是为零。你可能想要'360/fromIntegral points'。 – sclv 2011-04-04 19:55:58