2
votes

In GHCiOnline, let listRestDiv 4 = floor(4/(fromInteger (nextPrimeDiv 4))) does work, but the general

let listRestDiv n = floor(n/(fromInteger (nextPrimeDiv n)))

is not accepted, where nextPrimeDiv n is given by

let nextPrimeDiv n = head [x|x<-[1..n], n `mod` x == 0, x/=1]

and just returns the next prime divisor.

It says:

Could not deduce (RealFrac Integer) arising from a use of `floor' from the context (Integral b) bound by the inferred type of listRestDiv :: Integral b => Integer -> b at

and ends there. I just dont get the types right here. Thanks in advance for any hint.

1
it's good practice to add the type, and in this case it will solve the problem.Karoly Horvath
As @KarolyHorvath indicates, it is good practice to write type signatures for all top-level identifiers, and also for some non-top-level identifiers and expressions. Doing so lets you check in with the compiler to make sure the two of you agree on the type of what you've defined before moving on to other things. Although this particular problem is a fairly simple one, you will, one day, get some horrible type checker spew that makes no sense to you—adding as many type signatures as you can will help you figure out exactly where the error is. The ScopedTypeVariables will help a lot sometimes.dfeuer

1 Answers

4
votes

The actual complete error message received, hints us the fix to this problem.

Prelude> let listRestDiv n = floor(n/(fromInteger (nextPrimeDiv n)))

<interactive>:8:21:
    Could not deduce (RealFrac Integer) arising from a use of `floor'
    from the context (Integral b)
      bound by the inferred type of
               listRestDiv :: Integral b => Integer -> b
      at <interactive>:8:5-59
    Possible fix: add an instance declaration for (RealFrac Integer)
    In the expression: floor (n / (fromInteger (nextPrimeDiv n)))
    In an equation for `listRestDiv':
        listRestDiv n = floor (n / (fromInteger (nextPrimeDiv n)))

<interactive>:8:28:
    Could not deduce (Fractional Integer) arising from a use of `/'
    from the context (Integral b)
      bound by the inferred type of
               listRestDiv :: Integral b => Integer -> b
      at <interactive>:8:5-59
    Possible fix: add an instance declaration for (Fractional Integer)
    In the first argument of `floor', namely
      `(n / (fromInteger (nextPrimeDiv n)))'
    In the expression: floor (n / (fromInteger (nextPrimeDiv n)))
    In an equation for `listRestDiv':
        listRestDiv n = floor (n / (fromInteger (nextPrimeDiv n)))

The important thing to be noted here is

    Possible fix: add an instance declaration for (Fractional Integer)
    In the first argument of `floor', namely
      `(n / (fromInteger (nextPrimeDiv n)))'

So, all you have to do is, use fromInteger for n also, like this

Prelude> let listRestDiv n = floor(fromInteger n/(fromInteger (nextPrimeDiv n)))