为什么这个Haskell类型的强制不能编译?

cri*_*eep 2 haskell casting

啊.以下代码无法编译:

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

抛出以下错误:

  • "使用"sqrt"时没有(浮动整数)的实例

请帮忙?我显然不习惯Haskell强制.

PS:离开toInteger编译但在运行时抛出类型歧义错误.

lef*_*out 6

始终使用类型签名开始设计Haskell函数是非常明智的,然后才编写实现.在这种情况下,您可能想要

factorsOf :: Integer -> [(Integer, Integer)]
Run Code Online (Sandbox Code Playgroud)

因此,在内部factorsOf n = ...,变量n将具有类型Integer.这就是问题所在:你试图取一个整数的平方根,但sqrt只是在浮点数上定义.所以你需要获取root 之前转换为这样的数字.在root之后,你会想要截断一个整数,但是floor已经这样做了.toInteger不需要.

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