2013-08-16 32 views
14

我想了一年多的复合增长率,但我不关心小数点,所以我试图转换整数到双哈斯克尔

take 52 $ iterate (floor . (*1.1)) 100 

的问题是,(floor . (*1.1))类型是Double -> Integer,而类型为迭代的第一个参数的预期值为a -> a

我尝试了几种方法,但最终以束缚结束了自己。

保持函数应用程序中数值类型一致的首选解决方案是什么?

+4

你不能围绕中间结果四舍五入,并希望在最后得到正确的答案。为什么不把'floor'移出'iterate'并做'map floor。拿52 $ ...'? – Fixnum

+0

@Fixnum公平点,当我遇到问题时,这只是我试图用ghci运行的东西。 –

回答

18

的一般方法的Int转换为Double是使用fromIntegral,其具有类型(Integral a, Num b) => a -> b。这意味着它会将Integral类型(IntInteger)转换为任何数字类型b,其中Double是一个实例。

你的情况听起来好像要到Double转换为Int,这我会建议floor的,但你必须确保你的输入是Double。对于这一点,你可以使用fromIntegral功能与

take 52 $ iterate (floor . (* 1.1) . fromIntegral) 100 

然而,这会给你不准确的结果,因为你是在每一步截断。我建议你做

take 52 $ map floor $ iterate (* 1.1) $ fromIntegral 100 
+0

我还会补充一点,后面的表达式会稍微快一点,因为'fromIntegral'执行一次,'(* 1.1)'仍然重复,并且'floor'只执行尽可能多的次数,尽管可以进行参数调换'地图地板'和'取52'。 – bheklilr

+3

相当写成: '拿52。地图楼层。迭代(* 1.1)。从整合$ 100' – Davorak