-- 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.1 -- | 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 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 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 (/) :: 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 (Eq a, Show a, 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 fromRational :: Fractional a => Rational -> a -- | Integral numbers, supporting integer division. -- -- Minimal complete definition: toInteger. class (Real a, Enum a, EuclideanDomain a) => Integral a 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 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 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 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)