thor
thor

Reputation: 22530

Type ambiguity of arithmetic expression when wrapped in a function

I am writing a simple function on the GHCi command line (7.8.3)

let roundBy b x = (round (x/b)) * b

When evaluated, it gives an error about ambiguity (error message at bottom).

However, if I substitute the values, the same expression can be evaluated fine.

Prelude> (round (3/10))*10
0

My question is:

Is there a way to make ghci behave the same when the expression is encapsulated in a function, in the above case?

P.S. Error message (when evaluated as a function):

Prelude> roundBy 10 3

<interactive>:19:1:
    No instance for (Show a0) arising from a use of `print'
    The type variable `a0' is ambiguous
    Note: there are several potential instances:
      instance Show Double -- Defined in `GHC.Float'
      ...plus 23 others
    In a stmt of an interactive GHCi command: print it

Upvotes: 1

Views: 53

Answers (1)

Random Dev
Random Dev

Reputation: 52290

it's tricky but the thing is that the two 10s in (round (3/10))*10 don't have to be the same type but of course the bs in let roundBy b x = (round (x/b)) * b have to be.

That`s why:

λ> :t (round (3/10))*10
(round (3/10))*10 :: Integral a => a

but

λ> :t roundBy 10 3
roundBy 10 3 :: (RealFrac a, Integral a) => a

and GHCi just knows how to default to Integral a but obviously does not for RealFrac a, Integral a


so to really behave the same you would need:

let roundBy b b' x = (round (x/b)) * b'

and indeed:

λ> roundBy 10 10 3
0

how to fix it

I forgot to add how to fix the problem here - I think you really want this:

let roundBy b x = (round (x/fromIntegral b)) * b

with this you get:

λ> :t roundBy
roundBy :: (Integral a, Integral a1) => a -> a1 -> a
λ> roundBy 10 3
0

by the way: it's usually a good idea to give the indented types for your function ;) so we can help you better

another way to do it

From the looks of it you can simplify this function a bit using rem:

λ> let roundBy b x = x - x `rem` b
λ> roundBy 10 3
0
λ> roundBy 10 13
10

Upvotes: 3

Related Questions