这个Haskell函数的类型签名是什么?

Jer*_*ten 4 haskell types type-inference

我写了一个函数来检查数字是否为素数:

prime n = prime' n 2 (floor (sqrt n))
     where prime' n c u | n `mod` c == 0 = False
                        | c > u = True
                        | otherwise = prime' n (c+1) u
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚这个函数的类型签名应该是什么.起初我认为它应该是这样的:

prime :: Integral a => a -> Bool
Run Code Online (Sandbox Code Playgroud)

但是在编译时我会遇到错误,因为sqrt期望a Floating a而且floor期望a RealFrac a而不是a Integral a.当我删除类型签名时,它会编译,但该函数不起作用:

*Euler> :t prime
prime :: (Integral a, RealFrac a, Floating a) => a -> Bool
*Euler> prime 5

<interactive>:1:0:
    Ambiguous type variable `t' in the constraints:
      `Floating t' arising from a use of `prime' at <interactive>:1:0-6
      `RealFrac t' arising from a use of `prime' at <interactive>:1:0-6
      `Integral t' arising from a use of `prime' at <interactive>:1:0-6
    Probable fix: add a type signature that fixes these type variable(s)
Run Code Online (Sandbox Code Playgroud)

如何使此功能起作用?

new*_*cct 12

问题是你使用sqrton n,强制n为浮点数; 并且你也使用modon n,强制n为整数.直观地说,从查看你的代码,n 应该是一个整数,所以你不能直接调用sqrt它.相反,您可以使用类似的东西fromIntegral将其从整数转换为另一种数字类型.

prime :: (Integral a) => a -> Bool
prime n = prime' n 2 (floor (sqrt (fromIntegral n)))
     where prime' n c u | n `mod` c == 0 = False
                        | c > u = True
                        | otherwise = prime' n (c+1) u
Run Code Online (Sandbox Code Playgroud)