Reputation: 6798
I use (^) :: (Num a, Integral b) => a -> b -> a
a lot to define constant factors or sizes. Problem is that GHC complains about defaulting to Integer
.
Now I know why this happens ... and I know that I can "just" write (x^(y::Int))
to get rid of the warning. But that looks just "ugly". Otoh living with the warnings is also not a great option.
Same thing applies for (^^) :: (Integral b, Fractional a) => a -> b -> a
and (**) :: Floating a => a -> a -> a
is not usable to me.
Anyone has a nice solution to this (first world) problem?
Just found this gem of code:
alignment a = 2 ^ ceiling (logBase 2 (fromIntegral (sizeOf a)))
This is one LOC and GHC complains about defaulting to Integer
and Double
on the same line.
Upvotes: 1
Views: 246
Reputation: 64740
I've seen some people explicitly type their literals in a single location. I don't think it is the right solution for your case, the times I've seen it the issue was always Int/Integer ambiguity, but for the record:
two :: Int
two = 2
twoDbl :: Double
twoDbl = 2
... two ^ blah
where ...
sizeLb = logBase twoDbl ...
Upvotes: 0
Reputation: 34378
If you don't want defaulting, you need the type annotations somewhere. An alternative to inline type annotations for places where they look too ugly are local definitions with signatures:
alignment :: Storable a => a -> Int
alignment a = 2 ^ (ceiling sizeLb :: Int)
where
sizeLb :: Double
sizeLb = logBase 2 (fromIntegral (sizeOf a))
Upvotes: 1
Reputation: 2818
You could define your own operator with a more specific type. Or you could redefine the (^)
operator with a more specific type, like this:
import Prelude hiding ((^))
import qualified Prelude ((^))
(^) :: Num a => a -> Int -> a
(^) = (Prelude.^)
x :: Int
x = 2^3
Upvotes: 7