简体   繁体   中英

Why won't this Haskell type coercion compile?

Ugh. The following code fails to compile:

factorsOf number = [(x, quot number x) | x <- [2..toInteger $ floor $ sqrt number], number `mod` x == 0]

The following error is thrown:

  • "No instance for (Floating Integer) arising from a use of `sqrt'"

Please help? I'm clearly not grokking Haskell coercion.

PS: Leaving off toInteger compiles but throws a type-ambiguity error at runtime.

It is highly advisable to always start design of a Haskell function with the type signature , and only then write the implementation. In this case, you probably want

factorsOf :: Integer -> [(Integer, Integer)]

So, within factorsOf n = ... , the variable n will have type Integer . That's the problem: you're trying to take the square root of an integer, but sqrt is only defined on floating numbers. So you need to convert to such a number before taking the root. After the root, you'll then want to truncate back to an integer, but floor already does that. toInteger is not needed.

factorsOf :: Integer -> [(Integer, Integer)]
factorsOf n
     = [ (x, n`quot`x)
       | x <- [2 .. floor . sqrt $ fromIntegral n]
       , n `mod` x == 0
       ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM