簡體   English   中英

使用 HUnit 在 Doubles 上測試 haskell 相等性?

[英]Testing haskell equality on Doubles with HUnit?

HUnit 有什么方法可以做近似等式嗎? 顯然,這失敗了:

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

對於浮點近似比較,有一個帶有一些不錯的工具的庫:

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

自從第一次提出這個問題以來, HUnit-approx軟件包已經發布。

它使用隱式變量epsilon和近似相等運算符~?~代替~=? .

一個簡短的例子:

tweak :: Float -> Float
tweak x = x * 1.0001

egApproxTest  = let ?epsilon = 0.01 in
    [ "strictEqual" ~: 0 ~=? tweak 0,
      "approxEqual" ~: 2 ~?~ tweak 2 ]

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


這是 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的用於測試雙重相等的功能 ,我們可以使用相同的樣式創建自己的樣式:

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 ...

就我的目的而言,此輔助功能運行良好:

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

我將數據類型設置為等於代碼的實例,以使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM