Boolean 0.1.2 → 0.2
raw patch · 3 files changed
+233/−29 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.Boolean: atan2 :: RealFloatB a => a -> a -> a
- Data.Boolean: class (Boolean (BooleanOf a), RealFrac a, Floating a) => RealFloatB a
- Data.Boolean: instance RealFloatB Double
- Data.Boolean: instance RealFloatB Float
- Data.Boolean: isIEEE :: RealFloatB a => a -> BooleanOf a
- Data.Boolean: isInfinite :: RealFloatB a => a -> BooleanOf a
- Data.Boolean: isNaN :: RealFloatB a => a -> BooleanOf a
- Data.Boolean: isNegativeZero :: RealFloatB a => a -> BooleanOf a
+ Data.Boolean: caseB :: (IfB b, bool ~ BooleanOf b) => a -> [(a -> bool, b)] -> b -> b
+ Data.Boolean: guardedB :: (IfB b, bool ~ BooleanOf b) => bool -> [(bool, b)] -> b -> b
+ Data.Boolean.Numbers: atan2 :: RealFloatB a => a -> a -> a
+ Data.Boolean.Numbers: ceiling :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b
+ Data.Boolean.Numbers: class (NumB a, OrdB a) => IntegralB a where quot = fst .: quotRem rem = snd .: quotRem div = fst .: divMod mod = snd .: divMod quotRem = quot ## rem divMod = div ## mod
+ Data.Boolean.Numbers: class Num a => NumB a where type family IntegerOf a
+ Data.Boolean.Numbers: class (Boolean (BooleanOf a), RealFracB a, Floating a) => RealFloatB a
+ Data.Boolean.Numbers: class (NumB a, OrdB a, Fractional a) => RealFracB a where truncate = fst . properFraction
+ Data.Boolean.Numbers: div :: IntegralB a => a -> a -> a
+ Data.Boolean.Numbers: divMod :: IntegralB a => a -> a -> (a, a)
+ Data.Boolean.Numbers: evenB :: (IfB a, EqB a, IntegralB a) => a -> BooleanOf a
+ Data.Boolean.Numbers: floor :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b
+ Data.Boolean.Numbers: fromIntegerB :: NumB a => IntegerOf a -> a
+ Data.Boolean.Numbers: fromIntegralB :: (IntegerOf a ~ IntegerOf b, IntegralB a, NumB b) => a -> b
+ Data.Boolean.Numbers: instance IntegralB Int
+ Data.Boolean.Numbers: instance IntegralB Integer
+ Data.Boolean.Numbers: instance NumB Double
+ Data.Boolean.Numbers: instance NumB Float
+ Data.Boolean.Numbers: instance NumB Int
+ Data.Boolean.Numbers: instance NumB Integer
+ Data.Boolean.Numbers: instance RealFloatB Double
+ Data.Boolean.Numbers: instance RealFloatB Float
+ Data.Boolean.Numbers: instance RealFracB Double
+ Data.Boolean.Numbers: instance RealFracB Float
+ Data.Boolean.Numbers: isIEEE :: RealFloatB a => a -> BooleanOf a
+ Data.Boolean.Numbers: isInfinite :: RealFloatB a => a -> BooleanOf a
+ Data.Boolean.Numbers: isNaN :: RealFloatB a => a -> BooleanOf a
+ Data.Boolean.Numbers: isNegativeZero :: RealFloatB a => a -> BooleanOf a
+ Data.Boolean.Numbers: mod :: IntegralB a => a -> a -> a
+ Data.Boolean.Numbers: oddB :: (IfB a, EqB a, IntegralB a) => a -> BooleanOf a
+ Data.Boolean.Numbers: properFraction :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> (b, a)
+ Data.Boolean.Numbers: quot :: IntegralB a => a -> a -> a
+ Data.Boolean.Numbers: quotRem :: IntegralB a => a -> a -> (a, a)
+ Data.Boolean.Numbers: rem :: IntegralB a => a -> a -> a
+ Data.Boolean.Numbers: round :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b
+ Data.Boolean.Numbers: toIntegerB :: IntegralB a => a -> IntegerOf a
+ Data.Boolean.Numbers: truncate :: (RealFracB a, IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b
Files
- Boolean.cabal +7/−5
- src/Data/Boolean.hs +16/−24
- src/Data/Boolean/Numbers.hs +210/−0
Boolean.cabal view
@@ -1,6 +1,6 @@ Name: Boolean-Version: 0.1.2-Synopsis: Generalized booleans+Version: 0.2+Synopsis: Generalized booleans and numbers Category: Data Cabal-Version: >= 1.6 Description:@@ -8,12 +8,13 @@ Starting with 0.1.0, this package uses type families. Up to version 0.0.2, it used MPTCs with functional dependencies. My thanks to Andy Gill for suggesting & helping with the change.- Thanks also to Alex Horsman for the overloading module.+ Thanks also to Alex Horsman for Data.Boolean.Overload and to+ Jan Bracker for Data.Boolean.Numbers. .- Copyright 2009-2012 Conal Elliott; BSD3 license.+ Copyright 2009-2013 Conal Elliott; BSD3 license. Author: Conal Elliott Maintainer: conal@conal.net-Copyright: (c) 2009-2012 by Conal Elliott+Copyright: (c) 2009-2013 by Conal Elliott License: BSD3 License-File: COPYING Stability: experimental@@ -30,6 +31,7 @@ Exposed-Modules: Data.Boolean Data.Boolean.Overload+ Data.Boolean.Numbers ghc-options: -Wall -- ghc-prof-options: -prof -auto-all
src/Data/Boolean.hs view
@@ -34,15 +34,16 @@ ---------------------------------------------------------------------- module Data.Boolean- (- Boolean(..), BooleanOf, IfB(..), boolean, cond, crop- , EqB(..), OrdB(..), RealFloatB(..), minB, maxB, sort2B+ ( Boolean(..), BooleanOf, IfB(..)+ , boolean, cond, crop+ , EqB(..), OrdB(..)+ , minB, maxB, sort2B+ , guardedB, caseB ) where import Data.Monoid (Monoid,mempty) import Control.Applicative (Applicative(pure),liftA2,liftA3) - {-------------------------------------------------------------------- Classes --------------------------------------------------------------------}@@ -82,6 +83,16 @@ crop :: (Applicative f, Monoid (f a), IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a crop r f = cond r f mempty +-- | A generalized replacement for guards and chained ifs.+guardedB :: (IfB b, bool ~ BooleanOf b) => bool -> [(bool,b)] -> b -> b+guardedB _ [] e = e+guardedB a ((c,b):l) e = ifB c b (guardedB a l e)++-- | A generalized version of a case like control structure.+caseB :: (IfB b, bool ~ BooleanOf b) => a -> [(a -> bool, b)] -> b -> b+caseB _ [] e = e+caseB x ((p,b):l) e = ifB (p x) b (caseB x l e)+ infix 4 ==*, /=* -- | Types with equality. Minimum definition: '(==*)'.@@ -110,13 +121,8 @@ sort2B :: (IfB a, OrdB a) => (a,a) -> (a,a) sort2B (u,v) = ifB (u <=* v) (u,v) (v,u) -class (Boolean (BooleanOf a), RealFrac a, Floating a) => RealFloatB a where- isNaN :: a -> BooleanOf a- isInfinite :: a -> BooleanOf a- isNegativeZero :: a -> BooleanOf a- isIEEE :: a -> BooleanOf a- atan2 :: a -> a -> a + {-------------------------------------------------------------------- Instances for Prelude types --------------------------------------------------------------------}@@ -152,20 +158,6 @@ SimpleTy(Char) -- Similarly for other simple types.--instance RealFloatB Float where- isNaN = Prelude.isNaN- isInfinite = Prelude.isInfinite- isNegativeZero = Prelude.isNegativeZero- isIEEE = Prelude.isIEEE- atan2 = Prelude.atan2--instance RealFloatB Double where- isNaN = Prelude.isNaN- isInfinite = Prelude.isInfinite- isNegativeZero = Prelude.isNegativeZero- isIEEE = Prelude.isIEEE- atan2 = Prelude.atan2 -- TODO: Export these macros for external use. I guess I'd want a .h file as in -- the applicative-numbers package.
+ src/Data/Boolean/Numbers.hs view
@@ -0,0 +1,210 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleContexts #-}++{-# OPTIONS_GHC -Wall #-}++-- -----------------------------------------------------------------------+-- |+-- Module : Data.Boolean.Numbers+-- Copyright : (c) Jan Bracker 2013+-- License : BSD3+-- +-- Maintainer : jbra@informatik.uni-kiel.de+-- Stability : experimental+-- +-- A generalized version of the class hirarchy for numbers. All+-- functions that would break a potential deep embedding are removed+-- or generalized to support deep embeddings.+-- +-- The class hirarchy for numeric types keeps as close as possible to the +-- 'Prelude' hirarchy. A great part of the default implementation and comments+-- are copied and adopted from 'Prelude'.+-- -----------------------------------------------------------------------++module Data.Boolean.Numbers + ( NumB(..)+ , IntegralB(..)+ , RealFracB(..)+ , RealFloatB(..)+ , evenB, oddB+ , fromIntegralB+ ) where++import Prelude hiding + ( quotRem, divMod+ , quot, rem+ , div, mod+ , properFraction+ , fromInteger, toInteger )+import qualified Prelude as P++import Control.Arrow (first)++import Data.Boolean++{--------------------------------------------------------------------+ Misc+--------------------------------------------------------------------}++infixr 9 .:++-- Double composition. (Aka "result.result". See semantic editor combinators.)+(.:) :: (c -> c') -> (a -> b -> c) -> (a -> b -> c')+(.:) = (.).(.)++(##) :: (a -> b -> c) -> (a -> b -> d) -> a -> b -> (c,d)+(f ## g) x y = (f x y, g x y)++-- -----------------------------------------------------------------------+-- Generalized Number Class Hirarchy+-- -----------------------------------------------------------------------++-- | An extension of 'Num' that supplies the integer type of a +-- given number type and a way to create that number from the +-- integer.+class Num a => NumB a where+ -- | The accociated integer type of the number.+ type IntegerOf a+ -- | Construct the number from the associated integer.+ fromIntegerB :: IntegerOf a -> a++-- | A deep embedded version of 'Integral'.+-- Integral numbers, supporting integer division.+-- +-- Minimal complete definition is either 'quotRem' and 'divMod'+-- or the other four functions. Besides that 'toIntegerB' always+-- has to be implemented.+class (NumB a, OrdB a) => IntegralB a where+ -- | Integer division truncated towards zero.+ quot :: a -> a -> a+ quot = fst .: quotRem+ -- | Integer reminder, satisfying:+ -- @(x `quot` y) * y + (x `rem` y) == x@+ rem :: a -> a -> a+ rem = snd .: quotRem+ -- | Integer division truncated toward negative infinity.+ div :: a -> a -> a+ div = fst .: divMod+ -- | Integer modulus, satisfying:+ -- @(x `div` y) * y + (x `mod` y) == x@+ mod :: a -> a -> a+ mod = snd .: divMod+ -- | Simultaneous 'quot' and 'rem'.+ quotRem :: a -> a -> (a,a)+ quotRem = quot ## rem+ -- | Simultaneous 'div' and 'mod'.+ divMod :: a -> a -> (a,a)+ divMod = div ## mod+ -- | Create a integer from this integral.+ toIntegerB :: a -> IntegerOf a++-- | Deep embedded version of 'RealFloat'.+-- Extracting components of fractions.+-- +-- Minimal complete definition: 'properFraction', +-- 'round', 'floor' and 'ceiling'.+class (NumB a, OrdB a, Fractional a) => RealFracB a where+ -- | The function 'properFraction' takes a real fractional number @x@+ -- and returns a pair @(n,f)@ such that @x = n+f@, and:+ -- + -- * @n@ is an integral number with the same sign as @x@; and+ -- + -- * @f@ is a fraction with the same type and sign as @x@,+ -- and with absolute value less than @1@.+ -- + -- The default definitions of the 'ceiling', 'floor', 'truncate'+ -- and 'round' functions are in terms of 'properFraction'.+ properFraction :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> (b, a)+ -- | @'truncate' x@ returns the integer nearest @x@ between zero and @x@+ truncate :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b+ truncate = fst . properFraction+ -- | @'round' x@ returns the nearest integer to @x@;+ -- the even integer if @x@ is equidistant between two integers+ round :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b+ -- | @'ceiling' x@ returns the least integer not less than @x@+ ceiling :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b+ -- | @'floor' x@ returns the greatest integer not greater than @x@.+ floor :: (IntegerOf a ~ IntegerOf b, IntegralB b) => a -> b++-- | Deep embedded version of 'RealFloat'.+-- Efficient, machine-independent access to the components of a+-- floating-point number.+-- +-- A complete definition has to define all functions.+class (Boolean (BooleanOf a), RealFracB a, Floating a) => RealFloatB a where+ -- | 'true' if the argument is an IEEE \"not-a-number\" (NaN) value.+ isNaN :: a -> BooleanOf a+ -- | 'true' if the argument is an IEEE infinity or negative infinity.+ isInfinite :: a -> BooleanOf a+ -- | 'true' if the argument is an IEEE negative zero.+ isNegativeZero :: a -> BooleanOf a+ -- | 'true' if the argument is an IEEE floating point number.+ isIEEE :: a -> BooleanOf a+ -- | a version of arctangent taking two real floating-point arguments.+ -- For real floating @x@ and @y@, @'atan2' y x@ computes the angle+ -- (from the positive x-axis) of the vector from the origin to the+ -- point @(x,y)@. @'atan2' y x@ returns a value in the range [@-pi@,+ -- @pi@]. It follows the Common Lisp semantics for the origin when+ -- signed zeroes are supported. @'atan2' y 1@, with @y@ in a type+ -- that is 'RealFloatB', should return the same value as @'atan' y@.+ atan2 :: a -> a -> a++-- -----------------------------------------------------------------------+-- Generalized Number Utility Functions+-- -----------------------------------------------------------------------++-- | Variant of 'even' for generalized booleans.+evenB :: (IfB a, EqB a, IntegralB a) => a -> BooleanOf a+evenB n = n `rem` 2 ==* 0++-- | Variant of 'odd' for generalized booleans.+oddB :: (IfB a, EqB a, IntegralB a) => a -> BooleanOf a+oddB = notB . evenB++-- | Variant of 'fromIntegral' for generalized booleans.+fromIntegralB :: (IntegerOf a ~ IntegerOf b, IntegralB a, NumB b) => a -> b+fromIntegralB = fromIntegerB . toIntegerB++-- -----------------------------------------------------------------------+-- Default Class Instances for Basic Types+-- -----------------------------------------------------------------------++-- | Only for internal use.+fromInteger' :: (Integer ~ IntegerOf b, NumB b) => Integer -> b+fromInteger' = fromIntegralB++#define DefaultNumBInstance(Ty) \+instance NumB (Ty) where {\+ type IntegerOf (Ty) = Integer ;\+ fromIntegerB = P.fromInteger }++#define DefaultIntegralBInstance(Ty) \+instance IntegralB (Ty) where {\+ quotRem = P.quotRem ;\+ divMod = P.divMod ;\+ toIntegerB = P.toInteger }++#define DefaultRealFracFloatBInstance(Ty) \+instance RealFracB (Ty) where {\+ properFraction = first fromInteger' . P.properFraction ;\+ round = fromInteger' . P.round ;\+ floor = fromInteger' . P.floor ;\+ ceiling = fromInteger' . P.ceiling };\+instance RealFloatB (Ty) where {\+ isNaN = P.isNaN ;\+ isInfinite = P.isInfinite ;\+ isNegativeZero = P.isNegativeZero ;\+ isIEEE = P.isIEEE ;\+ atan2 = P.atan2 }++DefaultNumBInstance(Int)+DefaultNumBInstance(Integer)+DefaultNumBInstance(Float)+DefaultNumBInstance(Double)++DefaultIntegralBInstance(Int)+DefaultIntegralBInstance(Integer)++DefaultRealFracFloatBInstance(Float)+DefaultRealFracFloatBInstance(Double)