-- 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:
--
--
-- - 0.0: initial version
-- - 0.1: moved fromRational back to Fractional, as it
-- isn't well-behaved for all fields. Removed realToField.
-- - 0.2: removed Eq and Show constraints from
-- Num, following base-4.5.
--
@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
--
--
-- - associate (gcd x y) == gcd x y,
-- and
-- - any common factor of x and y is a factor of
-- gcd x y.
--
gcd :: EuclideanDomain a => a -> a -> a
-- | lcm x y is a common multiple of x and
-- y such that
--
--
-- - associate (lcm x y) == lcm x y,
-- and
-- - any common multiple of x and y is a multiple of
-- lcm x y.
--
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)