packages feed

extended-reals (empty) → 0.1.0.0

raw patch · 6 files changed

+409/−0 lines, 6 filesdep +HUnitdep +QuickCheckdep +basesetup-changed

Dependencies added: HUnit, QuickCheck, base, deepseq, extended-reals, hashable, test-framework, test-framework-hunit, test-framework-quickcheck2, test-framework-th

Files

+ .travis.yml view
@@ -0,0 +1,56 @@+# NB: don't set `language: haskell` here++# The following enables several GHC versions to be tested; often it's enough to test only against the last release in a major GHC version. Feel free to omit lines listings versions you don't need/want testing for.+env:+# - GHCVER=6.12.3+# - GHCVER=7.0.1+# - GHCVER=7.0.2+# - GHCVER=7.0.3+# - GHCVER=7.0.4+# - GHCVER=7.2.1+# - GHCVER=7.2.2+# - GHCVER=7.4.1+# - GHCVER=7.4.2+# - GHCVER=7.6.1+# - GHCVER=7.6.2+ - GHCVER=7.6.3+# - GHCVER=7.8.1 # see note about Alex/Happy+# - GHCVER=7.8.2 # see note about Alex/Happy+ - GHCVER=7.8.3 # see note about Alex/Happy+# - GHCVER=head  # see section about GHC HEAD snapshots++# Note: the distinction between `before_install` and `install` is not important.+before_install:+ - travis_retry sudo add-apt-repository -y ppa:hvr/ghc+ - travis_retry sudo apt-get update+ - travis_retry sudo apt-get install cabal-install-1.18 ghc-$GHCVER # see note about happy/alex+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/1.18/bin:$PATH+ - |+   if [ $GHCVER = "head" ] || [ ${GHCVER%.*} = "7.8" ]; then+     travis_retry sudo apt-get install happy-1.19.3 alex-3.1.3+     export PATH=/opt/alex/3.1.3/bin:/opt/happy/1.19.3/bin:$PATH+   else+     travis_retry sudo apt-get install happy alex+   fi++install:+ - cabal update+ - cabal install --only-dependencies --enable-tests -v2  # -v2 provides useful information for debugging++# Here starts the actual work to be performed for the package under test; any command which exits with a non-zero exit code causes the build to fail.+script:+ - cabal configure --enable-tests -v2  # -v2 provides useful information for debugging+ - cabal build   # this builds all libraries and executables (including tests/benchmarks)+ - cabal test+ - cabal check+ - cabal sdist   # tests that a source-distribution can be generated++# The following scriptlet checks that the resulting source distribution can be built & installed+ - export SRC_TGZ=$(cabal-1.18 info . | awk '{print $2 ".tar.gz";exit}') ;+   cd dist/;+   if [ -f "$SRC_TGZ" ]; then+      cabal install "$SRC_TGZ";+   else+      echo "expected '$SRC_TGZ' not found";+      exit 1;+   fi
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Masahiro Sakai++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Masahiro Sakai nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ extended-reals.cabal view
@@ -0,0 +1,37 @@+name:                extended-reals+version:             0.1.0.0+synopsis:            Extension of real numbers with positive/negative infinities+description:+  Extension of real numbers with positive/negative infinities (±∞).+  It is useful for describing various limiting behaviors in mathematics.+homepage:            https://github.com/msakai/extended-reals/+license:             BSD3+license-file:        LICENSE+author:              Masahiro Sakai+maintainer:          masahiro.sakai@gmail.com+category:            Math+build-type:          Simple+extra-source-files:  .travis.yml+cabal-version:       >=1.10+bug-reports:         https://github.com/msakai/extended-reals/issues++source-repository head+  type:     git+  location: git://github.com/msakai/extended-reals.git++library+  exposed-modules:     Data.ExtendedReal+  other-extensions:    DeriveDataTypeable+  build-depends:       base >=4 && <5, deepseq >=1.3 && <1.4, hashable >=1.2 && <1.3+  hs-source-dirs:      src+  default-language:    Haskell2010++Test-suite TestExtendedReal+  Type:              exitcode-stdio-1.0+  HS-Source-Dirs:    test+  Main-is:           TestExtendedReal.hs+  Build-depends:     base, HUnit >=1.2 && <1.3, QuickCheck >=2.6 && <2.7, test-framework >=0.8 && <0.9, test-framework-th >=0.2 && <0.3, test-framework-hunit >=0.3 && <0.4, test-framework-quickcheck2 >=0.3 && <0.4, extended-reals+  Default-Language: Haskell2010+  Other-Extensions:+     TemplateHaskell+     ScopedTypeVariables
+ src/Data/ExtendedReal.hs view
@@ -0,0 +1,130 @@+{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE DeriveDataTypeable #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.ExtendedReal+-- Copyright   :  (c) Masahiro Sakai 2014+-- License     :  BSD-style+-- +-- Maintainer  :  masahiro.sakai@gmail.com+-- Stability   :  provisional+-- Portability :  non-portable (DeriveDataTypeable)+--+-- Extension of real numbers with positive/negative infinities (±∞).+-- It is useful for describing various limiting behaviors in mathematics.+--+-- Remarks:+--+-- * @∞ - ∞@ is left undefined as usual,+--   but we define @0 × ∞ = 0 × -∞ = 0@ by following the convention of+--   probability or measure theory.+--+-- References:+--+-- * Wikipedia contributors, "Extended real number line," Wikipedia,+--   The Free Encyclopedia, https://en.wikipedia.org/wiki/Extended_real_number_line+--   (accessed September 1, 2014).+--+-----------------------------------------------------------------------------+module Data.ExtendedReal+  ( Extended (..)+  , isFinite+  , isInfinite+  ) where++import Prelude hiding (isInfinite)+import Control.DeepSeq+import Data.Data+import Data.Hashable+import Data.Typeable++-- | @Extended r@ is an extension of /r/ with positive/negative infinity (±∞).+data Extended r+  = NegInf    -- ^ negative infinity (-∞)+  | Finite !r -- ^ finite value+  | PosInf    -- ^ positive infinity (+∞)+  deriving (Ord, Eq, Show, Read, Typeable, Data)++instance Bounded (Extended r) where+  minBound = NegInf+  maxBound = PosInf++instance Functor Extended where+  fmap _ NegInf = NegInf+  fmap f (Finite x) = Finite (f x)+  fmap _ PosInf = PosInf++instance NFData r => NFData (Extended r) where+  rnf (Finite x) = rnf x+  rnf _ = ()++instance Hashable r => Hashable (Extended r) where+  hashWithSalt s NegInf     = s `hashWithSalt` (0::Int)+  hashWithSalt s (Finite x) = s `hashWithSalt` (1::Int) `hashWithSalt` x+  hashWithSalt s PosInf     = s `hashWithSalt` (2::Int)++-- | @isFinite x = not (isInfinite x)@.+isFinite :: Extended r -> Bool+isFinite (Finite _) = True+isFinite _ = False++-- | @isInfinite x@ returns @True@ iff @x@ is @PosInf@ or @NegInf@.+isInfinite :: Extended r -> Bool+isInfinite = not . isFinite++-- | Note that @Extended r@ is /not/ a field, nor a ring.+-- +-- @PosInf + NegInf@ is left undefined as usual,+-- but we define @0 * PosInf = 0 * NegInf = 0@ by following the convention of probability or measure theory.+instance (Num r, Ord r) => Num (Extended r) where+  Finite a + Finite b = Finite (a+b)+  PosInf + NegInf = error "PosInf + NegInf is undefined"+  NegInf + PosInf = error "NegInf + PosInf is undefined"+  PosInf + _ = PosInf+  _ + PosInf = PosInf+  NegInf + _ = NegInf+  _ + NegInf = NegInf++  Finite x1 * e = scale x1 e+  e * Finite x2 = scale x2 e+  PosInf * PosInf = PosInf+  PosInf * NegInf = NegInf+  NegInf * PosInf = NegInf+  NegInf * NegInf = PosInf++  negate NegInf = PosInf+  negate (Finite x) = Finite (negate x)+  negate PosInf = NegInf++  abs NegInf = PosInf+  abs (Finite x) = Finite (abs x)+  abs PosInf = PosInf++  signum NegInf = Finite (-1)+  signum (Finite x) = Finite (signum x)+  signum PosInf = Finite 1++  fromInteger = Finite . fromInteger  ++-- | Note that @Extended r@ is /not/ a field, nor a ring.+instance (Fractional r, Ord r) => Fractional (Extended r) where+  recip (Finite x) = Finite (1/x)+  recip _ = Finite 0++  fromRational = Finite . fromRational++-- Note that we define @0 * PosInf = 0 * NegInf = 0@ by the convention of probability or measure theory.+scale :: (Num r, Ord r) => r -> Extended r -> Extended r+scale a e = seq e $+  case a `compare` 0 of+    EQ -> Finite 0+    GT ->+      case e of+        NegInf   -> NegInf+        Finite b -> Finite (a*b)+        PosInf   -> PosInf+    LT ->+      case e of+        NegInf   -> PosInf+        Finite b -> Finite (a*b)+        PosInf   -> NegInf
+ test/TestExtendedReal.hs view
@@ -0,0 +1,154 @@+{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}++import Prelude hiding (isInfinite)+import Control.Exception (SomeException, evaluate, try)+import Control.Monad+import Data.Maybe+import System.IO.Unsafe (unsafePerformIO)+import Test.HUnit hiding (Test)+import Test.QuickCheck+import Test.Framework.TH+import Test.Framework.Providers.HUnit+import Test.Framework.Providers.QuickCheck2++import Data.ExtendedReal++-- ----------------------------------------------------------------------++instance Arbitrary r => Arbitrary (Extended r) where+  arbitrary = +    oneof+    [ return NegInf+    , return PosInf+    , liftM Finite arbitrary+    ]++eval :: a -> Maybe a+eval a = unsafePerformIO $ do+  ret <- try (evaluate a)+  case ret of+    Left (_::SomeException) -> return Nothing+    Right b -> return $ Just b++isDefined :: a -> Bool+isDefined = isJust . eval++-- ----------------------------------------------------------------------++prop_add_comm :: Property+prop_add_comm =+  forAll arbitrary $ \(a :: Extended Rational) ->+  forAll arbitrary $ \b ->+    eval (a + b) == eval (b + a)++prop_add_assoc :: Property+prop_add_assoc =+  forAll arbitrary $ \(a :: Extended Rational) ->+  forAll arbitrary $ \b ->+  forAll arbitrary $ \c ->+    eval (a + (b + c)) == eval ((a + b) + c)++prop_add_unit :: Property+prop_add_unit =+  forAll arbitrary $ \(a :: Extended Rational) ->+    0 + a == a++prop_add_monotone :: Property+prop_add_monotone =+  forAll arbitrary $ \(a :: Extended Rational) ->+  forAll arbitrary $ \b ->+  forAll arbitrary $ \c ->+    a <= b && isDefined (a+c) && isDefined (b+c)+    ==> a+c <= b+c++prop_mult_comm :: Property+prop_mult_comm =+  forAll arbitrary $ \(a :: Extended Rational) ->+  forAll arbitrary $ \b ->+    a * b == b * a++-- PosInf + NegInf is left undefined+case_add_PosInf_NegInf :: IO ()+case_add_PosInf_NegInf =+  eval (PosInf + NegInf :: Extended Rational) @?= Nothing++prop_mult_assoc :: Property+prop_mult_assoc =+  forAll arbitrary $ \(a :: Extended Rational) ->+  forAll arbitrary $ \b ->+  forAll arbitrary $ \c ->+    a * (b * c) == (a * b) * c++prop_mult_unit :: Property+prop_mult_unit =+  forAll arbitrary $ \(a :: Extended Rational) ->+    1 * a == a++prop_mult_dist :: Property+prop_mult_dist =+  forAll arbitrary $ \(a :: Extended Rational) ->+  forAll arbitrary $ \b ->+  forAll arbitrary $ \c ->+    isDefined (a * (b + c)) && isDefined (a * b + a * c)+    ==> eval (a * (b + c)) == eval (a * b + a * c)++prop_mult_zero :: Property+prop_mult_zero = +  forAll arbitrary $ \(a :: Extended Rational) ->+    0 * a == 0++prop_mult_monotone :: Property+prop_mult_monotone =+  forAll arbitrary $ \(a :: Extended Rational) ->+  forAll arbitrary $ \b ->+  forAll arbitrary $ \c ->+    a <= b && c > 0 && isDefined (a*c) && isDefined (b*c)+    ==> a*c <= b*c++-- We define 0 * PosInf = 0+case_mult_zero_PosInf :: IO ()+case_mult_zero_PosInf =+  0 * PosInf @?= (0 :: Extended Rational)++-- We define 0 * NegInf = 0+case_mult_zero_NegInf :: IO ()+case_mult_zero_NegInf =+  0 * NegInf @?= (0 :: Extended Rational)++prop_negate_inverse :: Property+prop_negate_inverse = +  forAll arbitrary $ \(a :: Extended Rational) ->+    negate (negate a) == a++prop_signum_abs :: Property+prop_signum_abs =+  forAll arbitrary $ \(a :: Extended Rational) ->+    signum a * abs a == a++prop_recip_inverse :: Property+prop_recip_inverse =+  forAll arbitrary $ \(a :: Extended Rational) ->+    isFinite a && a /= 0 ==> recip (recip a) == a++case_recip_PosInf :: IO ()+case_recip_PosInf = recip PosInf @?= (0 :: Extended Rational)++case_recip_NegInf :: IO ()+case_recip_NegInf = recip NegInf @?= (0 :: Extended Rational)++prop_NegInf_smallest :: Property+prop_NegInf_smallest =+  forAll arbitrary $ \(a :: Extended Rational) ->+    NegInf <= a++prop_PosInf_largest :: Property+prop_PosInf_largest =+  forAll arbitrary $ \(a :: Extended Rational) ->+    a <= PosInf++-- ----------------------------------------------------------------------+-- Test harness++main :: IO ()+main = $(defaultMainGenerator)