我经常使用(^) :: (Num a, Integral b) => a -> b -> a
来定义常数因子或大小。问题是GHC抱怨默认为Integer
。
现在我知道为什么会发生这种情况......我知道我可以“只是”写(x^(y::Int))
来摆脱警告。但这看起来只是“丑陋”。生活在警告中的奥托也不是一个很好的选择。
同样的事情适用于(^^) :: (Integral b, Fractional a) => a -> b -> a
,而(**) :: Floating a => a -> a -> a
对我来说无法使用。
对于这个(第一世界)问题,任何人都有一个很好的解决方案吗?
刚刚发现这个代码宝石:
alignment a = 2 ^ ceiling (logBase 2 (fromIntegral (sizeOf a)))
这是一个LOC和GHC抱怨在同一行上默认为Integer
和Double
。
答案 0 :(得分:7)
您可以使用更具体的类型定义自己的运算符。或者您可以使用更具体的类型重新定义(^)
运算符,如下所示:
import Prelude hiding ((^))
import qualified Prelude ((^))
(^) :: Num a => a -> Int -> a
(^) = (Prelude.^)
x :: Int
x = 2^3
答案 1 :(得分:1)
如果您不想要默认,则需要在某处进行类型注释。对于看起来太丑陋的地方的内联类型注释的替代方法是具有签名的本地定义:
alignment :: Storable a => a -> Int
alignment a = 2 ^ (ceiling sizeLb :: Int)
where
sizeLb :: Double
sizeLb = logBase 2 (fromIntegral (sizeOf a))
答案 2 :(得分:0)
我见过有些人在一个地方明确输入他们的文字。我不认为这是适合你的情况的正确解决方案,我看到它的问题始终是Int / Integer模糊,但是为了记录:
two :: Int
two = 2
twoDbl :: Double
twoDbl = 2
... two ^ blah
where ...
sizeLb = logBase twoDbl ...