我正在尝试实现一个简单的功能:totient
:
coprime :: Integral a => a -> a -> Bool
coprime a b = gcd a b == 1
totient :: Integral a => a -> a
totient m = length $ filter (coprime m) [1..m-1]
ghci> :load 99problems.hs
[1 of 1] Compiling Main ( 99problems.hs, interpreted )
99problems.hs:250:13: error:
• Couldn't match expected type ‘a’ with actual type ‘Int’
‘a’ is a rigid type variable bound by
the type signature for:
totient :: forall a. Integral a => a -> a
at 99problems.hs:249:12
• In the expression: length $ filter (coprime m) [1 .. m - 1]
In an equation for ‘totient’:
totient m = length $ filter (coprime m) [1 .. m - 1]
• Relevant bindings include
m :: a (bound at 99problems.hs:250:9)
totient :: a -> a (bound at 99problems.hs:250:1)
Failed, modules loaded: none.
我尝试在fromIntegral
上使用toInteger
或(m-1)
之类的东西,但没有一个起作用。我不确定我在这里缺少什么...似乎Int
应该是类型Integral a => a
。怎么了?
答案 0 :(得分:5)
类型Integral a => a -> a
说:
a
类型。a
是Integral
的实例。a
的值。a
类型的值。但是,在这种情况下,实现者产生了Int
。每当调用者选择a
作为不是Integral
的{{1}}的实例时,这将与调用者的类型不匹配。