用HUnit测试双打上的haskell平等?

时间:2012-02-16 19:55:27

标签: haskell

HUnit是否有某种方式做出近似的平等?显然,这失败了:

test1 = TestCase (assertEqual "Should equal" (get_scores) [(0.3, 0.3), (0.6, 0.36), (1.0, 0.3399999)])

4 个答案:

答案 0 :(得分:3)

对于浮点近似比较,有一个带有一些很好的工具库的库:

http://hackage.haskell.org/package/ieee754

答案 1 :(得分:1)

注意:我不知道是否有正确/官方/可接受的方式来执行此操作。


Here's assertEqual的源代码:

assertEqual :: (Eq a, Show a) => String -- ^ The message prefix 
                              -> a      -- ^ The expected value 
                              -> a      -- ^ The actual value
                              -> Assertion
assertEqual preface expected actual =
  unless (actual == expected) (assertFailure msg)
 where msg = (if null preface then "" else preface ++ "\n") ++
             "expected: " ++ show expected ++ "\n but got: " ++ show actual

基于此,在JUnit's function for testing double equality上,我们可以创建自己的风格:

import Control.Monad (unless)

assertEquals ::   String  -- ^ The message prefix
               -> Double  -- ^ The maximum difference between expected and actual
               -> Double  -- ^ The expected value
               -> Double  -- ^ The actual value
               -> Assertion
assertEquals preface delta expected actual = 
  unless (abs (expected - actual) < delta) (assertFailure msg)
 where msg = ... same as above ...

答案 2 :(得分:0)

就我的目的而言,这个助手功能运作良好:

assertFloatEqual text a b = 
  assertEqual text (take 6 (show a)) (take 6 (show b))

答案 3 :(得分:0)

我使我的数据类型与代码相等的实例使用2个小数位。以下是使用笛卡尔点的示例:

data Point =  Point { x_axis :: Double, y_axis :: Double, z_axis :: Double } 
              deriving (Show)

等于

的实例

为了避免双舍入误差和导致的三角错误 由于微小的差异,同一点,因此CornerPoints为/=, 给它一个.01的范围,并且仍然允许这些点相等。

axisEqual :: (Eq a, Num a, Ord a, Fractional a) => a -> a -> Bool

axisEqual  a b
  | (abs (a - b)) <= 0.011 = True
  | otherwise      = False

instance Eq Point where

  Point x y z == Point xa ya za
    | (axisEqual x xa) && (axisEqual y ya)  &&(axisEqual z za) = True 
    | otherwise = False