-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | yet another prelude - a simplistic refactoring with algebraic classes -- -- A simple refactoring of the Prelude numeric classes, attempting -- backwards compatibility for clients by defining a few algebraic -- classes as superclasses of the Haskell 98 numeric classes. This yields -- the following class hierarchy (grey classes are unchanged): -- -- -- Prelude.YAP is an almost-compatible replacement for the -- standard Haskell Prelude, as long as you're not defining instances of -- the numeric classes (though defaulting will be affected). When -- importing it, turn on RebindableSyntax. -- -- Data.YAP.Algebra contains just the new classes; you'll need to -- import it if you want access to the new names, including to define -- instances. -- -- Other modules contain some example instances, including for the -- existing types Complex and Ratio. -- -- History: -- -- @package yap @version 0.2 -- | Classes corresponding to common structures from abstract algebra. module Data.YAP.Algebra -- | An Abelian group has an commutative associative binary operation with -- an identity and inverses. -- -- Minimal complete definition: zero, (+) and -- ((-) or negate). class AbelianGroup a where x - y = x + negate y negate x = zero - x zero :: AbelianGroup a => a (+, -) :: AbelianGroup a => a -> a -> a negate :: AbelianGroup a => a -> a -- | A ring: addition forms an Abelian group, and multiplication defines a -- monoid and distributes over addition. Multiplication is not guaranteed -- to be commutative. -- -- Minimal complete definition: (*) and -- fromInteger. class AbelianGroup a => Ring a (*) :: Ring a => a -> a -> a fromInteger :: Ring a => Integer -> a -- | A integral domain (a non-trivial commutative Ring with no zero -- divisors) on which the Euclid's algorithm for gcd works. -- -- Minimal complete definition: (divMod or (div and -- mod)) and unit. class (Eq a, Ring a) => EuclideanDomain a where n divMod d = (n `div` d, n `mod` d) n div d = q where (q, _) = divMod n d n mod d = r where (_, r) = divMod n d associate x = x `div` unit x div, mod :: EuclideanDomain a => a -> a -> a divMod :: EuclideanDomain a => a -> a -> (a, a) associate, unit :: EuclideanDomain a => a -> a -- | A commutative Ring in which all non-zero elements have -- multiplicative inverses. -- -- Minimal complete definition: recip or (/). class Ring a => Field a where recip x = 1 / x x / y = x * recip y (/) :: Field a => a -> a -> a recip :: Field a => a -> a -- | The same as flip (-). -- -- Because - is treated specially in the Haskell grammar, -- (- e) is not a section, but an application of -- prefix negation. However, (subtract -- exp) is equivalent to the disallowed section. subtract :: AbelianGroup a => a -> a -> a -- | gcd x y is a common factor of x and -- y such that -- -- gcd :: EuclideanDomain a => a -> a -> a -- | lcm x y is a common multiple of x and -- y such that -- -- lcm :: EuclideanDomain a => a -> a -> a -- | A replacement for the standard Prelude, aiming to preserve -- compatibility for clients as far as possible. To use this module, -- you'll need to turn on RebindableSyntax, which also turns off -- the implicit import of the standard Prelude. -- -- For greater backwards compatibility, this module hides the names of -- the classes AbelianGroup, Ring, Field and -- EuclideanDomain, and their new methods zero, -- unit and associate. To use those names, e.g. to -- define instances, you'll also need to import Data.YAP.Algebra. module Prelude.YAP -- | Haskell 98 compatibility class class Ring a => Num a abs :: Num a => a -> a signum :: Num a => a -> a -- | unchanged from Haskell 98 class (Num a, Ord a) => Real a toRational :: Real a => a -> Rational -- | Haskell 98 compatibility class class (Num a, Field a) => Fractional a where fromRational x = fromInteger (numerator x) / fromInteger (denominator x) fromRational :: Fractional a => Rational -> a -- | Integral numbers, supporting integer division. -- -- Minimal complete definition: toInteger. class (Real a, Enum a, EuclideanDomain a) => Integral a where n quot d = q where (q, _) = quotRem n d n rem d = r where (_, r) = quotRem n d quotRem n d = if signum r == - signum d then (q + 1, r - d) else qr where qr@(q, r) = divMod n d quot :: Integral a => a -> a -> a rem :: Integral a => a -> a -> a quotRem :: Integral a => a -> a -> (a, a) toInteger :: Integral a => a -> Integer -- | unchanged from Haskell 98 class (Real a, Fractional a) => RealFrac a where truncate x = m where (m, _) = properFraction x round x = let (n, r) = properFraction x m = if r < 0 then n - 1 else n + 1 in case signum (abs r - 0.5) of { -1 -> n 0 -> if even n then n else m 1 -> m } ceiling x = if r > 0 then n + 1 else n where (n, r) = properFraction x floor x = if r < 0 then n - 1 else n where (n, r) = properFraction x properFraction :: (RealFrac a, Integral b) => a -> (b, a) truncate, round :: (RealFrac a, Integral b) => a -> b ceiling, floor :: (RealFrac a, Integral b) => a -> b -- | unchanged from Haskell 98 class Fractional a => Floating a where x ** y = exp (log x * y) logBase x y = log y / log x sqrt x = x ** 0.5 tan x = sin x / cos x tanh x = sinh x / cosh x pi :: Floating a => a exp, sqrt, log :: Floating a => a -> a (**, logBase) :: Floating a => a -> a -> a sin, tan, cos :: Floating a => a -> a asin, atan, acos :: Floating a => a -> a sinh, tanh, cosh :: Floating a => a -> a asinh, atanh, acosh :: Floating a => a -> a -- | unchanged from Haskell 98 class (RealFrac a, Floating a) => RealFloat a where exponent x = if m == 0 then 0 else n + floatDigits x where (m, n) = decodeFloat x significand x = encodeFloat m (- floatDigits x) where (m, _) = decodeFloat x scaleFloat k x = encodeFloat m (n + k) where (m, n) = decodeFloat x atan2 y x | x > 0 = atan (y / x) | x == 0 && y > 0 = pi / 2 | x < 0 && y > 0 = pi + atan (y / x) | (x <= 0 && y < 0) || (x < 0 && isNegativeZero y) || (isNegativeZero x && isNegativeZero y) = - atan2 (- y) x | y == 0 && (x < 0 || isNegativeZero x) = pi | x == 0 && y == 0 = y | otherwise = x + y floatRadix :: RealFloat a => a -> Integer floatDigits :: RealFloat a => a -> Int floatRange :: RealFloat a => a -> (Int, Int) decodeFloat :: RealFloat a => a -> (Integer, Int) encodeFloat :: RealFloat a => Integer -> Int -> a exponent :: RealFloat a => a -> Int significand :: RealFloat a => a -> a scaleFloat :: RealFloat a => Int -> a -> a isNaN, isIEEE, isNegativeZero, isDenormalized, isInfinite :: RealFloat a => a -> Bool atan2 :: RealFloat a => a -> a -> a even, odd :: Integral a => a -> Bool -- | raise a number to a non-negative integral power (^) :: (Ring a, Integral b) => a -> b -> a -- | raise a number to an integral power (^^) :: (Field a, Integral b) => a -> b -> a -- | General conversion from integral types, via the Integer type. fromIntegral :: (Integral a, Ring b) => a -> b -- | General conversion to fields, via the Rational type. realToFrac :: (Real a, Fractional b) => a -> b -- | Standard functions on rational numbers. -- -- This version uses the same type as Data.Ratio, but with -- components generalized from Integral to -- EuclideanDomain. However using the same type means we have -- the old, more constrained, instances of Ord, Show and -- Read. module Data.YAP.Ratio -- | Rational numbers, with numerator and denominator of some -- Integral type. data Ratio a :: * -> * -- | Arbitrary-precision rational numbers, represented as a ratio of two -- Integer values. A rational number may be constructed using the -- % operator. type Rational = Ratio Integer -- | Forms the ratio of two values in a Euclidean domain (e.g. -- Integer). (%) :: EuclideanDomain a => a -> a -> Ratio a -- | Extract the numerator of the ratio in reduced form: the numerator and -- denominator have no common factor and the denominator is positive. numerator :: EuclideanDomain a => Ratio a -> a -- | Extract the denominator of the ratio in reduced form: the numerator -- and denominator have no common factor and the denominator is positive. denominator :: EuclideanDomain a => Ratio a -> a -- | approxRational, applied to two real fractional numbers -- x and epsilon, returns the simplest rational number -- within epsilon of x. A rational number y is -- said to be simpler than another y' if -- -- -- -- Any real interval contains a unique simplest rational; in particular, -- note that 0/1 is the simplest rational of all. approxRational :: RealFrac a => a -> a -> Rational -- | A version of Data.Complex, using the same type, but with less -- constrained operations. In particular this version permits Gaussian -- integers. module Data.YAP.Complex -- | Complex numbers are an algebraic type. -- -- For a complex number z, abs z is a number -- with the magnitude of z, but oriented in the positive real -- direction, whereas signum z has the phase of -- z, but unit magnitude. data Complex a :: * -> * -- | forms a complex number from its real and imaginary rectangular -- components. (:+) :: !a -> !a -> Complex a -- | Extracts the real part of a complex number. realPart :: Complex a -> a -- | Extracts the imaginary part of a complex number. imagPart :: Complex a -> a -- | Form a complex number from polar components of magnitude and phase. mkPolar :: Floating a => a -> a -> Complex a -- | cis t is a complex value with magnitude 1 and -- phase t (modulo 2*pi). cis :: Floating a => a -> Complex a -- | The function polar takes a complex number and returns a -- (magnitude, phase) pair in canonical form: the magnitude is -- nonnegative, and the phase in the range (-pi, -- pi]; if the magnitude is zero, then so is the phase. polar :: RealFloat a => Complex a -> (a, a) -- | The nonnegative magnitude of a complex number. -- -- RealFloat is used to do scaling to reduce the incidence of -- overflow. magnitude :: RealFloat a => Complex a -> a -- | The phase of a complex number, in the range (-pi, -- pi]. If the magnitude is zero, then so is the phase. -- -- RealFloat is need for atan2. phase :: RealFloat a => Complex a -> a -- | The conjugate of a complex number. conjugate :: AbelianGroup a => Complex a -> Complex a instance RealFloat a => Floating (Complex a) instance RealFloat a => Fractional (Complex a) instance RealFloat a => Num (Complex a) instance RealFloat a => Field (Complex a) instance Integral a => EuclideanDomain (Complex a) instance Ring a => Ring (Complex a) instance AbelianGroup a => AbelianGroup (Complex a) -- | An example instance of the new classes: vectors. module Data.YAP.Vector -- | Simple vector type. newtype Vector a Vector :: [a] -> Vector a -- | Dot product of two vectors. dot :: Ring a => Vector a -> Vector a -> a -- | Norm of a vector. norm :: Ring a => Vector a -> a instance Eq a => Eq (Vector a) instance Show a => Show (Vector a) instance AbelianGroup a => AbelianGroup (Vector a) instance Functor Vector -- | An example instance of the new classes: arbitrary-sized matrices, -- based on a haskell-cafe posting by Udo Stenzel on 22 Jun 2006. -- -- Beware that the identity matrix is infinite. module Data.YAP.Matrix newtype Matrix a -- | list of rows Matrix :: [[a]] -> Matrix a -- | Multiply a matrix by a vector. apply :: Ring a => Matrix a -> Vector a -> Vector a instance Eq a => Eq (Matrix a) instance Show a => Show (Matrix a) instance Ring a => Ring (Matrix a) instance AbelianGroup a => AbelianGroup (Matrix a) instance Functor Matrix -- | An example instance of the new classes: polynomials. Some of these -- functions work with infinite polynomials, i.e. formal power series. module Data.YAP.Polynomial data Polynomial a -- | Construct a polynomial from a list of coefficients, least significant -- first. polynomial :: [a] -> Polynomial a -- | The coefficients of a finite polynomial, least significant first and -- with no trailing zeroes. coefficients :: (Eq a, AbelianGroup a) => Polynomial a -> [a] -- | The degree of a finite polynomial. -- --
--   degree p = length (coefficients p)
--   
degree :: (Eq a, AbelianGroup a) => Polynomial a -> Int -- | Evaluate a polynomial for a given value of x. -- --
--   evaluate a x = zipWith (*) (coefficients a) (iterate (*x) 1)
--   
-- -- (The implementation uses Horner's rule.) evaluate :: Ring a => Polynomial a -> a -> a -- | Pretty-print a polynomial, e.g. -- --
--   pretty (polynomial [3, 4, 0, 1, 5]) "x" = "5x^4 + x^3 + 4x + 3"
--   
pretty :: (Ord a, Show a, Ring a) => Polynomial a -> String -> String -- | The infinite list of evaluations of truncations of the polynomial or -- power series. approximations :: Ring a => Polynomial a -> a -> [a] -- | Composition of polynomials: -- --
--   evaluate (compose a b) = evaluate a . evaluate b
--   
compose :: Ring a => Polynomial a -> Polynomial a -> Polynomial a -- | Symbolic differentiation of polynomials. differentiate :: Ring a => Polynomial a -> Polynomial a -- | Symbolic integration of polynomials. integrate :: Field a => Polynomial a -> Polynomial a instance (Eq a, Field a) => EuclideanDomain (Polynomial a) instance Ring a => Ring (Polynomial a) instance AbelianGroup a => AbelianGroup (Polynomial a) instance (Eq a, Show a, AbelianGroup a) => Show (Polynomial a) instance (Eq a, AbelianGroup a) => Eq (Polynomial a) instance Functor Polynomial -- | An example instance of the new classes: numeric quantities with unit -- types. You can only compare and add quantities that use the same -- units. module Data.YAP.Quantity -- | Quantities of a numeric type a, in units encoded by the -- phantom type parameter u. For example, types for counting -- apples and oranges can be defined as: -- --
--   data Apple
--   data Orange
--   type Apples = Quantity Apple Int
--   type Oranges = Quantity Orange Int
--   
-- -- You can't compare Apples with Oranges (or add them). -- You can add Apples to Apples, but not multiply them. -- -- A full dimensional system keeping track of units while modelling -- multiplication and division will require type-level functions. newtype Quantity u a Quantity :: a -> Quantity u a instance Eq a => Eq (Quantity u a) instance Ord a => Ord (Quantity u a) instance Read a => Read (Quantity u a) instance Show a => Show (Quantity u a) instance AbelianGroup a => AbelianGroup (Quantity u a)