Haskell No instance for (Fractional a0) arising

荒凉一梦 提交于 2019-12-25 09:14:14

问题


I have the following code in 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

The code is loaded without any problem on ghci. The problem comes when I try to call the function part1 as:

part1 4 10 4

I get:

No instance for (Fractional a0) arising from a use of it' The type variablea0' is ambiguous Note: there are several potential instances: instance Integral a => Fractional (GHC.Real.Ratio a) -- Defined in GHC.Real' instance Fractional Double -- Defined inGHC.Float' instance Fractional Float -- Defined in GHC.Float' In the first argument ofprint', namely `it' In a stmt of an interactive GHCi command: print it

I don't understand this problem. Any help would be great. Thanks


回答1:


Your problem here is a very common one - it roots into you mixing (/) with Integral operations like mod - this leads to two constraints: one for Integral and one for Fractional (the (/)) - but there is no basic number type which is an instance of both of them - so you end up with unsolvable constraints and GHC(i) will not find a matching instance and complain.

Most of this becomes obvious if you signatures - yes you don't have to but as you can see here it's valuable to do so anyway.

Assuming you want to work over Integer you get this:

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

note that I replaced (/) with div? Haskell points you to this as soon as you include expected types.

also note that of course

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

will work as well




回答2:


I solved it. I needed some fromIntegral conversions. Final code:

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


来源:https://stackoverflow.com/questions/37144190/haskell-no-instance-for-fractional-a0-arising

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