Haskell没有(分数a0)出现的实例

时间:2016-05-10 16:30:35

标签: haskell

我在Haskell中有以下代码:

powmod base 1 m = mod base m
powmod base exp m | even exp  = mod (pow2 * pow2) m
                  | otherwise = mod (base * powmod base (exp - 1) m) m
     where
        pow2 = powmod base (div exp 2) m

part1 j n 0 = 0
part1 j n k = (part1 j n (k-1)) + (powmod 16 (n-k) r)/r
   where
     r = 8*k+j

在ghci上加载代码没有任何问题。当我尝试将函数part1称为:

时出现问题
part1 4 10 4

我明白了:

  

使用it' The type variable a0'产生的(分数a0)没有实例暧昧注意:有几种潜力   实例:实例积分a =>分数(GHC.Real.Ratio a)        - 定义于GHC.Real' instance Fractional Double -- Defined in GHC.Float'实例分数浮点数 - 在GHC.Float' In the first argument of print'中定义,即`it'在一个国家   交互式GHCi命令:打印它

我不明白这个问题。任何帮助都会很棒。感谢

2 个答案:

答案 0 :(得分:3)

这里的问题非常常见 - 它将(/)Integralmod操作混合在一起 - 这会导致两个约束:一个用于Integral和一个用于Fractional(/)) - 但没有基本数字类型,它们都是两者的实例 - 所以你最终得到无法解析的约束和GHC(i )找不到匹配的实例并抱怨。

如果您签名,大部分内容都会变得明显 - 是的,您不必这样做,但正如您在此处所看到的那样,无论如何这样做都很有价值。

假设你想要在Integer上工作,你就明白了:

part1 :: Integer -> Integer -> Integer -> Integer
part1 j n 0 = 0
part1 j n k = (part1 j n (k-1)) + (powmod 16 (n-k) r) `div` r
   where
     r = 8*k+j

请注意,我将(/)替换为div?只要包含预期类型,Haskell就会指出这一点。

当然要注意

part1 :: Integral a => a -> a -> a -> a

也可以使用

答案 1 :(得分:0)

我解决了。我需要一些来自整体转换。最终代码:

part1 :: Integer -> Integer -> Integer -> Double
part1 j n 0 = 0
part1 j n k =  (part1 j n (k-1)) + (fromIntegral (powmod 16 (n-k) r)) / fromIntegral r
 where
   r = 8*k+j