haskell - let 绑定(bind)中的类型变量不明确

标签 haskell types

我是 Haskell 的新手,有 C++ 和 Java 背景。有时,我会遇到 Haskell 类型系统的问题。我当前的错误是这段代码:

countIf :: (Integral b) => [a] -> (a -> Bool) -> b
countIf [] p = 0
countIf (x:xs) p
  | p x = 1 + countIf xs p
  | otherwise = countIf xs p

isRelativelyPrime :: (Integral a) => a -> a -> Bool
isRelativelyPrime m n = gcd m n == 1

phi :: (Integral a, Integral b) => a -> b
phi n = countIf [1..(n - 1)] (isRelativelyPrime n)

main = print [(n, phi n, ratio) | n <- [1..10], let ratio = (fromIntegral (phi n)) / n]

错误信息是

prog.hs:13:60:
    Ambiguous type variable `b' in the constraints:
      `Fractional b' arising from a use of `/' at prog.hs:13:60-85
      `Integral b' arising from a use of `phi' at prog.hs:13:75-79
    Probable fix: add a type signature that fixes these type variable(s)

13:60 就在我的 main 列表理解中的 let 绑定(bind)中使用 fromIntegral 之前。我仍在努力适应 ghc 的错误消息。我无法破译这个特定的问题,以便弄清楚我需要更改什么才能编译我的代码。任何帮助将不胜感激。谢谢。

最佳答案

这是初学者常见错误的示例:过多的多态代码

您已使代码尽可能通用,例如

phi :: (Integral a, Integral b) => a -> b

这将通过 phi 转换将任何整型类型转换为任何其他整型类型。

这样的多态代码对于库来说非常有用,但对于类型推断就不那么好了。我认为您只是希望它适用于整数,因此我们可以继续给出更准确的类型,

countIf :: [Integer] -> (Integer -> Bool) -> Integer
countIf [] p = 0
countIf (x:xs) p
  | p x       = 1 + countIf xs p
  | otherwise = countIf xs p

isRelativelyPrime :: Integer -> Integer -> Bool
isRelativelyPrime m n = gcd m n == 1

phi :: Integer -> Integer
phi n = countIf [1..(n - 1)] (isRelativelyPrime n)

main = print [ (n, phi n, ratio)
             | n <- [1..10], let ratio = (fromIntegral (phi n)) ]

类型错误就消失了。

您甚至可能会看到性能改进(特别是如果您专注于 Int)。

关于haskell - let 绑定(bind)中的类型变量不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10920634/

相关文章:

arrays - 由有界数据类型索引的 Repa 数组?

Haskell:类型不匹配

Haskell 记录更新

Objective-C 类型推断

c++ - 基本类型

haskell - 如何创建两个调用此外部库 API 的 ByteString?

haskell - new-template.cabal 和 stack.yaml 的区别

python | Pandas |对象 |转换为整数或 float

c++ - 为什么C++(Visual Studio)数据类型没有停止在其极限上?

python - "TEXTFILE = open(' x.txt' ,'a' )"中的变量是什么数据类型?