我在很多情况下使用 (^) :: (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
。
您可以使用更具体的类型定义自己的操作员。或者,您可以使用更具体的类型重新定义(^)
操作员,例如:
import Prelude hiding ((^))
import qualified Prelude ((^))
(^) :: Num a => a -> Int -> a
(^) = (Prelude.^)
x :: Int
x = 2^3
如果您不想默认,则需要某个地方的类型注释。在外观太丑陋的地方的内联类型注释的替代方案是带有签名的本地定义:
alignment :: Storable a => a -> Int
alignment a = 2 ^ (ceiling sizeLb :: Int)
where
sizeLb :: Double
sizeLb = logBase 2 (fromIntegral (sizeOf a))
我已经看到有些人在一个位置中明确键入他们的文字。我认为这不是适合您的情况的正确解决方案,我看过的时代一直是int/Integer歧义,但记录下:
two :: Int
two = 2
twoDbl :: Double
twoDbl = 2
... two ^ blah
where ...
sizeLb = logBase twoDbl ...