2

I am trying to define:

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

and I am getting:

<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)

I am still new in this language and I seem to be unable to convert an instance of Floating to an Integer. Does anybody know how can I do so?

3 Answers 3

5

Haskell has multiple exponent functions with different types:

The one you are looking for is just (^). With it, you don't even need round:

square :: Integer -> Integer 
square = (^ 2)
Sign up to request clarification or add additional context in comments.

Comments

5

This is an appendix to Alec's answer, which is correct, to help you understand the error message. The type of (**) is

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

So

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

(because the literal 2 can be any numeric type we need). But a is Integer because your function is declared to take an Integer as an input. So now

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

This explains your second error, because there is no FloatingInteger instance -- Integers do not support floating point operations like sin (and exponentiating with an arbitrary real number).

Then you pass the output of this function, which is an Integer, along to round which has type

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

We know the input, a, is Integer because it's coming from (** 2) as we discussed, and the output b is also Integer because the output of your function is declared to be Integer. So now you have

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

There is an IntegralInteger instance, so that is used, but there is no RealFracInteger instance, and that explains your first error. Integers do not support rational-like operations like extracting the numerator (though I suppose they could...).

Comments

1

As an appendix to @luqui's answer, if you wanted to fix the error (rather than just follow @Alec's excellent solution), you could convert the Integer parameter to a Floating instance first:

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

1 Comment

It is debatable whether luqui's answer could have been condensed to a comment on Alec's answer, but this certainly could have been a comment on luqui's answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.