我在文件main.hs中有以下代码:
teste :: Integral a => a -> a
teste n = truncate (sqrt n) + mod n 2
当我尝试加载它时,我从ghci中收到以下错误:
Prelude> :l main.hs
[1 of 1] Compiling Main ( main.hs, interpreted )
main.hs:12:11:
Could not deduce (RealFrac a) arising from a use of ‘truncate’
from the context (Integral a)
bound by the type signature for teste :: Integral a => a -> a
at main.hs:11:10-29
Possible fix:
add (RealFrac a) to the context of
the type signature for teste :: Integral a => a -> a
In the first argument of ‘(+)’, namely ‘truncate (sqrt n)’
In the expression: truncate (sqrt n) + mod n 2
In an equation for ‘teste’: teste n = truncate (sqrt n) + mod n 2
main.hs:12:21:
Could not deduce (Floating a) arising from a use of ‘sqrt’
from the context (Integral a)
bound by the type signature for teste :: Integral a => a -> a
at main.hs:11:10-29
Possible fix:
add (Floating a) to the context of
the type signature for teste :: Integral a => a -> a
In the first argument of ‘truncate’, namely ‘(sqrt n)’
In the first argument of ‘(+)’, namely ‘truncate (sqrt n)’
In the expression: truncate (sqrt n) + mod n 2
Failed, modules loaded: none.
但是当我在交互模式下运行相同的代码时,它运行良好:
Prelude> truncate (sqrt 5) + mod 5 2
3
答案 0 :(得分:6)
在您的通话truncate (sqrt 5) + mod 5 2
中,5
的类型不同。实际上,{{1}中的5
应该具有类型sqrt 5
,而Floating a => a
中的5
具有类型mod 5 2
。尽管严格说来,可以在Haskell中构造属于两个类型族的成员的类型,但是从概念上说,类型既是Integral b => b
也是Integral
,它也仅适用于此类类型,从而使其用处不大。因此,我们可以将签名更改为:
Floating
但是如前所述,这不是非常有用。
您可以在此处使用fromIntegral :: (Integral a, Num b) => a -> b
从teste :: (Integral a, Floating a, RealFrac a) => a -> a
teste n = truncate (sqrt n) + mod n 2
类型转换为任何Integral
类型,例如:
Num
例如:
teste :: Integral a => a -> a
teste n = truncate (sqrt (fromIntegral n)) + mod n 2