Reputation: 22530
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
Reputation: 52290
it's tricky but the thing is that the two 10
s in (round (3/10))*10
don't have to be the same type but of course the b
s 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
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
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