指数默认为整数

Exponents defaulting to Integer

我经常使用 (^) :: (Num a, Integral b) => a -> b -> a 来定义常数因子或大小。问题是 GHC 抱怨默认为 Integer.

现在我知道为什么会这样了...我知道我可以 "just" 写 (x^(y::Int)) 来消除警告。但这看起来只是 "ugly"。接受警告的 Otoh 也不是一个很好的选择。

同样适用于 (^^) :: (Integral b, Fractional a) => a -> b -> a(**) :: Floating a => a -> a -> a 对我来说不可用。

谁有解决这个(第一世界)问题的好方法?

编辑

刚找到这个 gem 代码:

alignment a = 2 ^ ceiling (logBase 2 (fromIntegral (sizeOf a)))

这是一个 LOC,GHC 抱怨在同一行默认为 IntegerDouble

您可以使用更具体的类型定义您自己的运算符。或者您可以使用更具体的类型重新定义 (^) 运算符,如下所示:

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