我是Haskell的新手,很好奇为什么这会导致错误。
sumtest :: (Real a) => [a] -> a
sumtest [] = 0
sumtest (x:xs) = x + sumtest xs
avgFunction :: (Integral a, Floating b) => [a] -> b
avgFunction a = sumtest a / length a
错误
ERROR file:code/test1.hs:114 - Inferred type is not general enough
*** Expression : avgFunction
*** Expected type : (Integral a, Floating b) => [a] -> b
*** Inferred type : (Integral Int, Floating Int) => [Int] -> Int
-----每个接受的答案下面的工作代码----
sumtest :: (Num a) => [a] -> a
sumtest [] = 0
sumtest (x:xs) = x + sumtest xs
avgFunction :: (Integral a, Floating b) => [a] -> b
avgFunction a = fromIntegral (sumtest a) / fromIntegral (length a)
sumtest a
type a
。我们知道这是一种Integral
类型。因此,无法分割的类型...length a
type Int
。这也是一种Integral
。(可能a
是另一种。)因此,您尝试将两个数相除,而这两个数的类型都无法相除。好吧,那行不通,对吗?
幸运的是,您可以转换数字。某些语言实际上是隐式地执行此操作(通常会导致各种破坏†),但Haskell则不会。好吧,但是它确实具有功能!hoogle是你的朋友:
avgFunction a = fromIntegral (sumtest a) / fromIntegral (length a)
length
到Int
或Double
。而且某些保守的隐式转换(例如Python)确实看起来并不算太糟糕。但是,任何类型的隐式转换都不适用于类似Haskell的Hindley-Milner类型的系统。
另一个需要注意的是:这些约束实际上是不必要的强大。以下内容就足够了:
avgFunction :: (Real a, Fractional b) => [a] -> b
avgFunction a = realToFrac (sumtest a) / realToFrac (length a)
这样,该函数还将允许Double
作为输入,而不仅仅是结果。(也许更容易了解发生了什么。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句