代码之家  ›  专栏  ›  技术社区  ›  Carlos Valiente

Int和Integer的不同行为?

  •  0
  • Carlos Valiente  · 技术社区  · 14 年前

    下面的代码片段包含 exercise 3 on page 69 mean 计算列表的平均值)。

    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
    
    1 回复  |  直到 14 年前
        1
  •  5
  •   jball    14 年前

    Int Integer 具有任意精度。因此,使用时可能会看到溢出或下溢 内景