Int和Integer的不同行为?

Car*_*nte 0 haskell

followng片段包含第69页练习3的解决方案(编写一个函数mean来计算列表的平均值).

在编写一些QuickCheck测试以验证其结果是否更加清晰时,我发现在我的系统上(ghc 6.12.3,Haskell平台2010.2.0.0在32-但是Ubuntu 10.4),测试适用于Integer输入,但不适用于Int那些.有什么想法吗?

import Test.QuickCheck

-- From text and previous exercises
data List a = Cons a (List a)
            | Nil
              deriving (Show)

fromList        :: [a] -> List a
fromList []     = Nil
fromList (x:xs) = Cons x (fromList xs)

listLength             :: List a -> Int
listLength Nil         = 0
listLength (Cons x xs) = 1 + listLength xs

-- Function ``mean`` is the aim of this exercise
mean             :: (Integral a) => List a -> Double
mean Nil         = 0
mean (Cons x xs) = (fromIntegral x + n * mean xs) / (n + 1)
    where n = fromIntegral (listLength xs)

-- To overcome rounding issues
almostEqual     :: Double -> Double -> Bool
almostEqual x y = (abs (x - y)) < 0.000001

-- QuickCheck tests for ``mean``
prop_like_arith_mean :: (Integral a) => [a] -> Property
prop_like_arith_mean xs = not (null xs) ==>
                          almostEqual
                          (mean (fromList xs))
                          (fromIntegral (sum xs) / fromIntegral (length xs))

prop_sum :: (Integral a) => [a] -> Bool
prop_sum xs = almostEqual
              (fromIntegral (length xs) * mean (fromList xs))
              (fromIntegral (sum xs))

-- This passes:
check_mean_ok =
    quickCheck (prop_like_arith_mean :: [Integer] -> Property) >>
    quickCheck (prop_sum :: [Integer] -> Bool)

-- This fails:
check_mean_fail =
    quickCheck (prop_like_arith_mean :: [Int] -> Property) >>
    quickCheck (prop_sum :: [Int] -> Bool)

main = check_mean_ok >>
       check_mean_fail
Run Code Online (Sandbox Code Playgroud)

jba*_*all 5

Int基于底层系统的int实现,并且可能与底层系统具有相同的下限和上限(但至少有[-2 ^ 29,2 ^ 29 - 1]的范围Integer具有任意精度.因此您可能是使用时看到溢出或下溢Int.