[The documentation is a lot better now. nad**20040617203012] { hunk ./ChasingBottoms/Approx.hs 5 - , module ChasingBottoms.Nat hunk ./ChasingBottoms/Approx.hs 178 - F is a functor : C^C x C^C -> (C x C)^C. + F is a functor : (C x C)^C -> (C x C)^C. hunk ./ChasingBottoms/Approx.hs 182 - Hence given an arrow (natural transformation) : (G, H) -> (G', H') - (G, G', H and H' objects (functors) in C^C) F yields an arrow + Hence given an arrow (natural transformation) + : forall a . G a -> (H a, K a) + (G, H and K objects (functors) in C^C) F yields an arrow hunk ./ChasingBottoms/ApproxShow.hs 9 - , module ChasingBottoms.Nat addfile ./ChasingBottoms/Header hunk ./ChasingBottoms/Header 1 +Do you ever feel the need to test code involving bottoms (e.g. calls to +the 'error' function), or code involving infinite values? Then this +library could be useful for you. + +It is usually easy to get a grip on bottoms by showing a value and +waiting to see how much gets printed before the first exception is +encountered. However, that quickly gets tiresome and is hard to automate +using e.g. QuickCheck +(). With this library you +can do the tests as simply as the following examples show. + +Testing explicitly for bottoms: + + [@> isBottom bottom@] @True@ + + [@> isBottom (\\_ -> bottom)@] @False@ + + [@> isBottom (bottom, bottom)@] @False@ + +Comparing finite, partial values: + + [@> ((bottom, 3) :: (Bool, Int)) ==! (bottom, 2+5-4)@] @True@ + + [@> ((bottom, bottom) :: (Bool, Int)) approxShow 4 $ (True, bottom) \\\/! (bottom, 'b')@] @\"Just (True, 'b')\"@ + + [@> approxShow 4 $ (True, bottom) \/\\! (bottom, 'b')@] @\"(_|_, _|_)\"@ + + [@> approxShow 4 $ ([1..\] :: [Int\])@] @\"[1, 2, 3, _\"@ + + [@> approxShow 4 $ (cycle [bottom\] :: [Bool\])@] @\"[_|_, _|_, _|_, _\"@ + +Approximately comparing infinite, partial values: + + [@> approx 100 [2,4..\] ==! approx 100 (filter even [1..\] :: [Int\])@] @True@ + + [@> approx 100 [2,4..\] \/=! approx 100 (filter even [bottom..\] :: [Int\])@] @True@ + +The code above relies on the fact that 'bottom', just as @'error' +\"...\"@, 'undefined' and pattern match failures, yield +exceptions. Sometimes we are dealing with properly non-terminating +computations, such as the following example, and then it can be nice to +be able to apply a timeout. + + [@> let primes = unfoldr (\\(x:xs) -> Just (x, filter ((\/= 0) . (\`mod\` x)) xs)) [2..\]@] + + [@> timeOutMicro 100 (print $ filter ((== 1) . (\`mod\` 32)) primes) >>= print@] @[97,193,257Nothing@ + + [@> timeOutMicro 100 (print $ take 5 $ filter ((== 1) . (\`mod\` 32)) primes) >>= print@] @[97,193,257,353Nothing@ + + [@> timeOutMicro 100 (print $ take 5 $ filter ((== 1) . (\`mod\` 32)) primes) >>= print@] @[97,193,257,353,449]@ + + [@ @] @Just ()@ + +All the type annotations above are required. + +For the underlying theory and a larger example involving use of +QuickCheck, see the article \"Chasing Bottoms, A Case Study in Program +Verification in the Presence of Partial and Infinite Values\" +(). + +The code is developed and tested under GHC. Most parts can probably be +ported to other Haskell compilers, but that would require some work. hunk ./ChasingBottoms/SemanticOrd.hs 15 - , module ChasingBottoms.IsBottom hunk ./ChasingBottoms/TimeOut.hs 22 --- resolution is not too great. +-- resolution is not necessarily very high (the last time I checked it +-- was 0.02 seconds). hunk ./ChasingBottoms/package 5 -ls ChasingBottoms/*hs | grep -v '/IsType.hs$' | \ - xargs haddock -h -oChasingBottoms/docs -tar zcvf ChasingBottoms/chasing-bottoms.tar.gz ChasingBottoms/*hs ChasingBottoms/docs/* +ls ChasingBottoms.hs ChasingBottoms/*hs | grep -v '/IsType.hs$' | \ + xargs haddock -h --title="Chasing Bottoms" --prologue=ChasingBottoms/Header \ + -oChasingBottoms/docs \ + && \ + tar zcvf ChasingBottoms/chasing-bottoms.tar.gz ChasingBottoms.hs \ + ChasingBottoms/*hs ChasingBottoms/docs/* addfile ./ChasingBottoms.hs hunk ./ChasingBottoms.hs 1 +-- | This module just re-exports all the other modules. + +module ChasingBottoms + ( module ChasingBottoms.Approx + , module ChasingBottoms.ApproxShow + , module ChasingBottoms.IsBottom + , module ChasingBottoms.Nat + , module ChasingBottoms.SemanticOrd + , module ChasingBottoms.TimeOut + ) where + +import ChasingBottoms.Approx +import ChasingBottoms.ApproxShow +import ChasingBottoms.IsBottom +import ChasingBottoms.Nat +import ChasingBottoms.SemanticOrd +import ChasingBottoms.TimeOut }