Exponents defaulting to Integer

此生再无相见时 提交于 2020-01-15 09:54:30

问题


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?

edit

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.


回答1:


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



回答2:


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



回答3:


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


来源:https://stackoverflow.com/questions/41144775/exponents-defaulting-to-integer

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!