将浮动转换为整数

时间:2016-11-28 12:02:10

标签: haskell

我想定义:

square :: Integer -> Integer 
square = round . (** 2)

我得到了:

<interactive>:9:9: error:
    • No instance for (RealFrac Integer) arising from a use of ‘round’
    • In the first argument of ‘(.)’, namely ‘round’
      In the expression: round . (** 2)
      In an equation for ‘square’: square = round . (** 2)

<interactive>:9:18: error:
    • No instance for (Floating Integer)
        arising from an operator section
    • In the second argument of ‘(.)’, namely ‘(** 2)’
      In the expression: round . (** 2)
      In an equation for ‘square’: square = round . (** 2)

我仍然是这种语言的新手,我似乎无法将Floating的实例转换为Integer。有谁知道我该怎么办?

3 个答案:

答案 0 :(得分:5)

Haskell有多个不同类型的指数函数:

您正在寻找的只是(^)。有了它,您甚至不需要round

square :: Integer -> Integer 
square = (^ 2)

答案 1 :(得分:5)

这是Alec答案的附录,这是正确的,可以帮助您理解错误信息。 (**)的类型是

(**) :: (Floating a) => a -> a -> a

所以

(** 2) :: (Floating a) => a -> a

(因为文字2可以是我们需要的任何数字类型)。但aInteger,因为您的函数声明为Integer作为输入。所以现在

(** 2) :: Integer -> Integer  --provided that there is a `Floating Integer` instance

这解释了您的第二个错误,因为没有Floating Integer实例 - Integer不支持sin等浮点运算(以及任意取幂)实数)。

然后将此函数的输出(Integer)传递给round,其类型为

round :: (RealFrac a, Integral b) => a -> b

我们知道输入aInteger,因为它来自我们讨论的(** 2),而输出b也是Integer,因为函数的输出声明为Integer。所以现在你有了

round :: Integer -> Integer  
    --provided there are `Integral Integer` and `RealFrac Integer` instaces

Integral Integer个实例,因此使用了该实例,但没有RealFrac Integer个实例,这解释了您的第一个错误。 Integer不支持类似于理性的操作,例如提取分子(尽管我认为它们可以......)。

答案 2 :(得分:1)

作为@ luqui回答的附录,如果您想修复错误(而不是仅仅关注@ Alec的优秀解决方案),您可以将Integer参数转换为{ {1}}实例优先:

Floating