show - Why does Haskell want this function's argument to have the type classes (RealFrac x, Integral x) when it only needs to be Integral x? -


i'm trying write code complete factorization of integer trial division. code seems ought work:

findafact :: integral x => x -> x findafact x = searchints [2, 3..] x     searchints (int:ints) div         | div `mod` int == 0 = int         | otherwise          = searchints ints div  completefacts :: integral x => x -> [x] completefacts x = tryforfact [] x     tryforfact fs x = if x == 1                       fs                       else let fact = findafact x                            in tryforfact (fact:fs) (floor ((fromintegral x) / fact)) 

but if try compile following error:

could not deduce (realfrac x) arising use of 'tryforfact' context (integral x)   bound type signature              completefacts :: integral x => x -> [x]   @ 5.hs:26:18-39 possible fix:   add (realfrac x) context of     type signature completefacts :: integral x => x -> [x] in expression: tryforfact [] x in equation 'completefacts':     completefacts x       = tryforfact [] x                 tryforfact fs x             = if x == 1                   fs               else                   let ... in tryforfact (fact : fs) (floor ((fromintegral x) / fact)) 

if remove type signature completefacts , try loading ghci, interpreter loads file , supplies type signature (realfrac x, integral x ) => x -> [x] completefacts, complains when try use completefacts there's no way show because type ambiguous in context of show. makes sense me because seems there clear way display x realfrac or integral, not both.

this seems offending code:

... in tryforfact (fact:fs) (floor ((fromintegral x) / fact)) 

i'm confused because i'd imagine passing x through fromintegral , passing result of division floor give me integral back. don't see why haskell still thinks x needs have type class realfrac. why haskell insist on this, , how can rewrite completefacts x can integral?

thanks!

it's because didn't convert fact realfrac before doing division:

in tryforfact (fact:fs) (floor (fromintegral x / fromintegral fact)) 

you've said fact = findafact x, has type integral x => x, you're using in division /, thinks needs satisfy both integral , realfrac.

what better use div instead (i've cleaned code little bit it's easier read , aren't shadowing existing binding x):

completefacts :: integral x => x -> [x] completefacts x = tryforfact [] x             tryforfact fs 1 = fs         tryforfact fs y = let fact = findafact y                           in tryforfact (fact:fs) (y `div` fact) 

Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -