【问题标题】:Haskell datatype conversion problemsHaskell 数据类型转换问题
【发布时间】:2011-03-26 22:26:04
【问题描述】:

我目前正在学习 Haskell,并且一直在编写一些非常简单的程序来练习。这些程序之一是我下面的那个:

import System.IO

main = do
    putStrLn "Give me year: "
    y <- getLine
    let res = show . calcPop $ read y
    putStrLn ("Population in " ++ y ++ " will be " ++ res)



pop :: Float
pop = 307357870.0
secInYear :: Float
secInYear = 365.0 * 24.0 * 60.0 * 60.0
bRate :: Float
bRate = secInYear / 7.0
dRate :: Float
dRate = secInYear / 13.0
iRate :: Float
iRate = secInYear / 35.0

calcPop :: Float -> Float
calcPop year = let years = year - 2010 in (years*bRate + years*iRate + pop - years*dRate)

它的作用是在 2010 年之后的一年内计算该年的估计人口,现在它工作正常,除了你可能已经注意到每个数字都被转换为浮点数。现在这样做非常荒谬,因为没有理由将当前人口,一年中的秒数或年份本身作为整数以外的任何东西,不幸的是,尽管当我以这种方式拥有它时,我得到了编译器/ 函数说有关小数 int 的错误,* 函数说它推断出浮点数作为第一个参数。现在我已经明白,当遇到涉及整数和浮点数的操作时,Haskell 像其他语言一样只会将 int 更改为像浮点数一样,这显然不会在这里发生。有人可以解释为什么我会遇到这些错误,以及我如何让整数和浮点数进行合作,因为显然我对 Haskell 类型系统的掌握还不够好,无法自己完成?

【问题讨论】:

    标签: haskell types


    【解决方案1】:

    Haskell 类型是严格的;它从不自动为您转换类型,除了整数文字自动包装在fromIntegral 中。相反,您可能希望在只需要处理Int/Integer 时使用更多类型适当的操作,例如`div`,并在需要时将fromIntegral 提升为FloatDouble

    (语法说明:`function` 将前缀函数转换为中缀运算符。)

    【讨论】:

      【解决方案2】:

      对于 Haskell 中的整数除法,您使用 divquot

      【讨论】:

        【解决方案3】:

        来自Haskell 98 language report

        一个整数字面量表示 函数的应用 从整数到适当的值 整数类型。同样,一个浮动 点字面量代表一个 fromRational 对值的应用 Rational 类型的(即 Ratio 整数)。

        这意味着源代码中的“7”变为“(fromInteger 7)”,“1.5”变为“(fromRational (3 Ratio.% 2))”。诸如 (+) 和 (/) 之类的数值运算具有诸如“a->a->a”之类的类型签名,这意味着它们是两个完全相同类型的参数并返回与给定相同的类型。这些标准运算符永远无法执行将 Float 添加到 Int 之类的操作。您可以编写 (fromIntegral) 来尝试将类似 Int 的类型提升为 Double 或 Float。

        【讨论】:

          猜你喜欢
          • 2010-12-29
          • 2020-09-25
          • 2015-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-23
          相关资源
          最近更新 更多