packages feed

Boolean 0.0.1 → 0.1.0

raw patch · 4 files changed

+95/−44 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Boolean: instance (IfB bool p, IfB bool q) => IfB bool (p, q)
- Data.Boolean: instance (IfB bool p, IfB bool q, IfB bool r) => IfB bool (p, q, r)
- Data.Boolean: instance (IfB bool p, IfB bool q, IfB bool r, IfB bool s) => IfB bool (p, q, r, s)
- Data.Boolean: instance EqB Bool Float
- Data.Boolean: instance EqB bool a => EqB (z -> bool) (z -> a)
- Data.Boolean: instance IfB Bool Float
- Data.Boolean: instance IfB bool a => IfB (z -> bool) (z -> a)
- Data.Boolean: instance OrdB Bool Float
- Data.Boolean: instance OrdB bool a => OrdB (z -> bool) (z -> a)
+ Data.Boolean: instance (Boolean (BooleanOf a), BooleanOf a ~ Bool) => IfB [a]
+ Data.Boolean: instance (bool ~ BooleanOf p, bool ~ BooleanOf q, IfB p, IfB q) => IfB (p, q)
+ Data.Boolean: instance (bool ~ BooleanOf p, bool ~ BooleanOf q, bool ~ BooleanOf r, IfB p, IfB q, IfB r) => IfB (p, q, r)
+ Data.Boolean: instance (bool ~ BooleanOf p, bool ~ BooleanOf q, bool ~ BooleanOf r, bool ~ BooleanOf s, IfB p, IfB q, IfB r, IfB s) => IfB (p, q, r, s)
+ Data.Boolean: instance EqB Bool
+ Data.Boolean: instance EqB Char
+ Data.Boolean: instance EqB Double
+ Data.Boolean: instance EqB Float
+ Data.Boolean: instance EqB Int
+ Data.Boolean: instance EqB Integer
+ Data.Boolean: instance EqB a => EqB (z -> a)
+ Data.Boolean: instance IfB Bool
+ Data.Boolean: instance IfB Char
+ Data.Boolean: instance IfB Double
+ Data.Boolean: instance IfB Float
+ Data.Boolean: instance IfB Int
+ Data.Boolean: instance IfB Integer
+ Data.Boolean: instance IfB a => IfB (z -> a)
+ Data.Boolean: instance OrdB Bool
+ Data.Boolean: instance OrdB Char
+ Data.Boolean: instance OrdB Double
+ Data.Boolean: instance OrdB Float
+ Data.Boolean: instance OrdB Int
+ Data.Boolean: instance OrdB Integer
+ Data.Boolean: instance OrdB a => OrdB (z -> a)
+ Data.Boolean: sort2B :: (IfB a, OrdB a) => (a, a) -> (a, a)
- Data.Boolean: (<*, >=*, >*, <=*) :: OrdB bool a => a -> a -> bool
+ Data.Boolean: (<*, >=*, >*, <=*) :: (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
- Data.Boolean: (==*, /=*) :: EqB bool a => a -> a -> bool
+ Data.Boolean: (==*, /=*) :: (EqB a, bool ~ BooleanOf a) => a -> a -> bool
- Data.Boolean: boolean :: IfB bool a => a -> a -> bool -> a
+ Data.Boolean: boolean :: (IfB a, bool ~ BooleanOf a) => a -> a -> bool -> a
- Data.Boolean: class Boolean bool => EqB bool a | a -> bool where u /=* v = notB (u ==* v)
+ Data.Boolean: class Boolean (BooleanOf a) => EqB a where u /=* v = notB (u ==* v)
- Data.Boolean: class Boolean bool => IfB bool a | a -> bool
+ Data.Boolean: class Boolean (BooleanOf a) => IfB a
- Data.Boolean: class Boolean bool => OrdB bool a | a -> bool where u >* v = v <* u u >=* v = notB (u <* v) u <=* v = v >=* u
+ Data.Boolean: class Boolean (BooleanOf a) => OrdB a where u >* v = v <* u u >=* v = notB (u <* v) u <=* v = v >=* u
- Data.Boolean: cond :: (Applicative f, IfB bool a) => f bool -> f a -> f a -> f a
+ Data.Boolean: cond :: (Applicative f, IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a -> f a
- Data.Boolean: crop :: (Applicative f, Monoid (f a), IfB bool a) => f bool -> f a -> f a
+ Data.Boolean: crop :: (Applicative f, Monoid (f a), IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a
- Data.Boolean: ifB :: IfB bool a => bool -> a -> a -> a
+ Data.Boolean: ifB :: (IfB a, bool ~ BooleanOf a) => bool -> a -> a -> a
- Data.Boolean: maxB :: (IfB bool a, OrdB bool a) => a -> a -> a
+ Data.Boolean: maxB :: (IfB a, OrdB a) => a -> a -> a
- Data.Boolean: minB :: (IfB bool a, OrdB bool a) => a -> a -> a
+ Data.Boolean: minB :: (IfB a, OrdB a) => a -> a -> a

Files

Boolean.cabal view
@@ -1,20 +1,26 @@ Name:                Boolean-Version:             0.0.1-Cabal-Version:       >= 1.2+Version:             0.1.0+Cabal-Version:       >= 1.6 Synopsis:            Generalized booleans Category:            Data Description:   Some classes for generalized boolean operations.+  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.   .-  Copyright 2009 Conal Elliott; BSD3 license.+  Copyright 2009-2012 Conal Elliott; BSD3 license. Author:              Conal Elliott Maintainer:          conal@conal.net-Package-Url:         http://code.haskell.org/~conal/code/Boolean-Copyright:           (c) 2009 by Conal Elliott+Copyright:           (c) 2009-2012 by Conal Elliott License:             BSD3 License-File:        COPYING Stability:           experimental build-type:          Simple++source-repository head+  type:     git+  location: git://github.com/conal/Boolean.git  Library   hs-Source-Dirs:      src
COPYING view
@@ -1,4 +1,4 @@-Copyright (c) 2009 Conal Elliott+Copyright (c) 2009-2012 Conal Elliott All rights reserved.  Redistribution and use in source and binary forms, with or without
− Makefile
@@ -1,1 +0,0 @@-include ../cho-home-cabal-make.inc
src/Data/Boolean.hs view
@@ -1,11 +1,16 @@ {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies            , UndecidableInstances, ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies, FlexibleContexts, CPP #-} {-# OPTIONS_GHC -Wall #-}++{-# OPTIONS_GHC -fno-warn-unused-imports #-} -- TEMP+{-# OPTIONS_GHC -fno-warn-unused-binds   #-} -- TEMP+ ---------------------------------------------------------------------- -- | -- Module      :  Data.Boolean--- Copyright   :  (c) Conal Elliott 2009+-- Copyright   :  (c) Conal Elliott 2009-2012 -- License     :  BSD3 --  -- Maintainer  :  conal@conal.net@@ -14,21 +19,24 @@ -- Some classes for generalized boolean operations. --  -- In this design, for if-then-else, equality and inequality tests, the--- boolean type depends functionally on the value type.  This dependency--- allows the boolean type to be inferred in a conditional expression.+-- boolean type depends on the value type. --  -- I also tried using a unary type constructor class.  The class doesn't work -- for regular booleans, so generality is lost.  Also, we'd probably have -- to wire class constraints in like: @(==*) :: Eq a => f Bool -> f a -> f -- a -> f a@, which disallows situations needing additional constraints, -- e.g., Show.--- +--+-- 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.+ ----------------------------------------------------------------------  module Data.Boolean   (-    Boolean(..),IfB(..), boolean, cond, crop-  , EqB(..), OrdB(..), minB, maxB+    Boolean(..), BooleanOf, IfB(..), boolean, cond, crop+  , EqB(..), OrdB(..), minB, maxB, sort2B   ) where  import Data.Monoid (Monoid,mempty)@@ -55,85 +63,121 @@   (&&*) = (&&)   (||*) = (||) +-- | 'BooleanOf' computed the boolean analog of a specific type.+type family BooleanOf a+ -- | Types with conditionals-class Boolean bool => IfB bool a | a -> bool where-  ifB  :: bool -> a -> a -> a+class Boolean (BooleanOf a) => IfB a where+  ifB  :: (bool ~ BooleanOf a) => bool -> a -> a -> a  -- | Expression-lifted conditional with condition last-boolean :: IfB bool a => a -> a -> bool -> a+boolean :: (IfB a, bool ~ BooleanOf a) => a -> a -> bool -> a boolean t e bool = ifB bool t e  -- | Point-wise conditional-cond :: (Applicative f, IfB bool a) => f bool -> f a -> f a -> f a+cond :: (Applicative f, IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a -> f a cond = liftA3 ifB --- | Crop a function, filling in 'mempty' where the test yeis false.-crop :: (Applicative f, Monoid (f a), IfB bool a) => f bool -> f a -> f a+-- | Generalized cropping, filling in 'mempty' where the test yields false.+crop :: (Applicative f, Monoid (f a), IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a crop r f = cond r f mempty - infix  4  ==*, /=*  -- | Types with equality.  Minimum definition: '(==*)'.-class Boolean bool => EqB bool a | a -> bool where-  (==*), (/=*) :: a -> a -> bool+class Boolean (BooleanOf a) => EqB a where+  (==*), (/=*) :: (bool ~ BooleanOf a) => a -> a -> bool   u /=* v = notB (u ==* v)  infix  4  <*, <=*, >=*, >*  -- | Types with inequality.  Minimum definition: '(<*)'.-class Boolean bool => OrdB bool a | a -> bool where-  (<*), (<=*), (>*), (>=*) :: a -> a -> bool+class Boolean (BooleanOf a) => OrdB a where+  (<*), (<=*), (>*), (>=*) :: (bool ~ BooleanOf a) => a -> a -> bool   u >*  v = v <* u   u >=* v = notB (u <* v)   u <=* v = v >=* u  -- | Variant of 'min' using 'ifB' and '(<=*)'-minB :: (IfB bool a, OrdB bool a) => a -> a -> a+minB :: (IfB a, OrdB a) => a -> a -> a u `minB` v = ifB (u <=* v) u v  -- | Variant of 'max' using 'ifB' and '(>=*)'-maxB :: (IfB bool a, OrdB bool a) => a -> a -> a+maxB :: (IfB a, OrdB a) => a -> a -> a u `maxB` v = ifB (u >=* v) u v +-- | Variant of 'min' using 'ifB' and '(<=*)'+sort2B :: (IfB a, OrdB a) => (a,a) -> (a,a)+sort2B (u,v) = ifB (u <=* v) (u,v) (v,u)+ {---------------------------------------------------------------------    Some instances+    Instances for Prelude types --------------------------------------------------------------------} +-- Simple if-then-else as function. ife :: Bool -> a -> a -> a ife c t e = if c then t else e  -- I'd give the following instances: -- ---     instance IfB  Bool a where ifB = ife---     instance EqB  Bool a where { (==*) = (==) ; (/=*) = (/=) }---     instance OrdB Bool a where { (<*) = (<) ; (<=*) = (<=)}+--     instance          IfB a where ifB = ife+--     instance Eq  a => EqB a where { (==*) = (==) ; (/=*) = (/=) }+--     instance Ord a => Ord a where { (<*) = (<) ; (<=*) = (<=)} --  -- Sadly, doing so would break the a->bool fundep, which is needed elsewhere -- for disambiguation.  So use the instances above as templates, filling -- in specific types for a. +#define SimpleInstances(Ty) \+instance IfB  (Ty) where { ifB = ife } ;\+instance EqB  (Ty) where { (==*) = (==) ; (/=*) = (/=) } ;\+instance OrdB (Ty) where { (<*) = (<) ; (<=*) = (<=) } -instance IfB  Bool Float where ifB = ife-instance EqB  Bool Float where { (==*) = (==) ; (/=*) = (/=) }-instance OrdB Bool Float where { (<*) = (<) ; (<=*) = (<=) }+#define SimpleTy(Ty) \+type instance BooleanOf (Ty) = Bool ;\+SimpleInstances(Ty) --- Similarly for other types.  +SimpleTy(Int)+SimpleTy(Integer)+SimpleTy(Float)+SimpleTy(Double)+SimpleTy(Bool)+SimpleTy(Char) +-- Similarly for other simple types. -instance (IfB bool p, IfB bool q) => IfB bool (p,q) where+-- TODO: Export these macros for external use. I guess I'd want a .h file as in+-- the applicative-numbers package.++type instance BooleanOf [a]       = BooleanOf a+type instance BooleanOf (a,b)     = BooleanOf a+type instance BooleanOf (a,b,c)   = BooleanOf a+type instance BooleanOf (a,b,c,d) = BooleanOf a+type instance BooleanOf (z -> a)  = z -> BooleanOf a++-- I'm uncomfortable with this list instance. It's unlike tuples and unlike+-- functions. It could be generalized from BooleanOf a ~ Bool to a general case+-- for applicatives, but then the list version would form cross products.+-- Consider strings and other list types under a variety of use scenarios.++instance (Boolean (BooleanOf a),BooleanOf a ~ Bool) => IfB [a] where { ifB = ife }++instance (bool ~ BooleanOf p, bool ~ BooleanOf q+         ,IfB p, IfB q) => IfB (p,q) where   ifB w (p,q) (p',q') = (ifB w p p', ifB w q q') -instance (IfB bool p, IfB bool q, IfB bool r) => IfB bool (p,q,r) where+instance (bool ~ BooleanOf p, bool ~ BooleanOf q, bool ~ BooleanOf r+         ,IfB p, IfB q, IfB r)+      => IfB (p,q,r) where   ifB w (p,q,r) (p',q',r') = (ifB w p p', ifB w q q', ifB w r r') -instance (IfB bool p, IfB bool q, IfB bool r, IfB bool s) => IfB bool (p,q,r,s) where+instance (bool ~ BooleanOf p, bool ~ BooleanOf q, bool ~ BooleanOf r, bool ~ BooleanOf s+         ,IfB p, IfB q, IfB r, IfB s) => IfB (p,q,r,s) where   ifB w (p,q,r,s) (p',q',r',s') =     (ifB w p p', ifB w q q', ifB w r r', ifB w s s') ----- Standard pattern for applicative functors:+-- Instances for functions, using the standard pattern for applicative functions.+-- Note that the [] applicative does not use this instance. Fishy.  instance Boolean bool => Boolean (z -> bool) where   true  = pure true@@ -142,14 +186,16 @@   (&&*) = liftA2 (&&*)   (||*) = liftA2 (||*) -instance IfB bool a => IfB (z -> bool) (z -> a) where+instance IfB a => IfB (z -> a) where   ifB = cond -instance EqB  bool a => EqB  (z -> bool) (z -> a) where+instance EqB a => EqB (z -> a) where   { (==*) = liftA2 (==*) ; (/=*) = liftA2 (/=*) }-instance OrdB bool a => OrdB (z -> bool) (z -> a) where-  { (<*) = liftA2(<*) ; (<=*) = liftA2(<=*) }+instance OrdB a => OrdB (z -> a) where+  { (<*) = liftA2 (<*) ; (<=*) = liftA2 (<=*) } +-- TODO: Generalize the function instance into a macro for arbitrary+-- applicatives. Instantiate for functions.  {-