packages feed

Boolean (empty) → 0.0.0

raw patch · 5 files changed

+220/−0 lines, 5 filesdep +basesetup-changed

Dependencies added: base

Files

+ Boolean.cabal view
@@ -0,0 +1,28 @@+Name:                Boolean+Version:             0.0.0+Cabal-Version:       >= 1.2+Synopsis:            Generalized boolean ops+Category:            Data+Description:+  Some classes for generalized boolean operations.+  .+  Copyright 2009 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+License:             BSD3+License-File:        COPYING+Stability:           experimental+build-type:          Simple++Library+  hs-Source-Dirs:      src+  Extensions:+  Build-Depends:       base<5+  Exposed-Modules:+                       Data.Boolean+                       +  ghc-options:         -Wall++--  ghc-prof-options:    -prof -auto-all 
+ COPYING view
@@ -0,0 +1,25 @@+Copyright (c) 2009 Conal Elliott+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. The names of the authors may not be used to endorse or promote products+   derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ Makefile view
@@ -0,0 +1,1 @@+include ../cho-home-cabal-make.inc
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ src/Data/Boolean.hs view
@@ -0,0 +1,163 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies+           , UndecidableInstances, ScopedTypeVariables+  #-}+{-# OPTIONS_GHC -Wall #-}+----------------------------------------------------------------------+-- |+-- Module      :  Data.Boolean+-- Copyright   :  (c) Conal Elliott 2009+-- License     :  BSD3+-- +-- Maintainer  :  conal@conal.net+-- Stability   :  experimental+-- +-- 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.+-- +-- 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.+-- +----------------------------------------------------------------------++module Data.Boolean+  (+    Boolean(..),IfB(..), boolean, cond, crop+  , EqB(..), OrdB(..)+  ) where++import Data.Monoid (Monoid,mempty)+import Control.Applicative (Applicative(..),liftA2,liftA3)+++{--------------------------------------------------------------------+    Classes+--------------------------------------------------------------------}++infixr 3  &&*+infixr 2  ||*++-- | Generalized boolean class+class Boolean b where+  true, false  :: b+  notB         :: b -> b+  (&&*), (||*) :: b -> b -> b++instance Boolean Bool where+  true  = True+  false = False+  notB  = not+  (&&*) = (&&)+  (||*) = (||)++-- | Types with conditionals+class Boolean bool => IfB bool a | a -> bool where+  ifB  :: bool -> a -> a -> a++-- | Expression-lifted conditional with condition last+boolean :: IfB bool 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 = 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+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+  u /=* v = notB (u ==* v)++infix  4  <*, <=*, >=*, >*++-- | Types with inequality.  Minimum definition: '(<*)'.+class Boolean bool => OrdB bool a | a -> bool where+  (<*), (<=*), (>*), (>=*) :: a -> a -> bool+  u >*  v = v <* u+  u >=* v = notB (u <* v)+  u <=* v = v >=* u++{--------------------------------------------------------------------+    Some instances+--------------------------------------------------------------------}++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 { (<*) = (<) ; (<=*) = (<=)}+-- +-- 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.+++instance IfB  Bool Float where ifB = ife+instance EqB  Bool Float where { (==*) = (==) ; (/=*) = (/=) }+instance OrdB Bool Float where { (<*) = (<) ; (<=*) = (<=) }++-- Similarly for other types.  +++instance (IfB bool p, IfB bool q) => IfB bool (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+  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+  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:++instance Boolean bool => Boolean (z -> bool) where+  true  = pure true+  false = pure false+  notB  = fmap notB+  (&&*) = liftA2 (&&*)+  (||*) = liftA2 (||*)++instance IfB bool a => IfB (z -> bool) (z -> a) where+  ifB = cond++instance EqB  bool a => EqB  (z -> bool) (z -> a) where+  { (==*) = liftA2 (==*) ; (/=*) = liftA2 (/=*) }+instance OrdB bool a => OrdB (z -> bool) (z -> a) where+  { (<*) = liftA2(<*) ; (<=*) = liftA2(<=*) }+++{-++{--------------------------------------------------------------------+    Tests+--------------------------------------------------------------------}++t1 :: String+t1 = ifB True "foo" "bar"++t2 :: Float -> Float+t2 = ifB (< 0) negate id++--     No instance for (IfB (a -> Bool) (a1 -> a1))+--       arising from a use of `ifB'+-- +-- t2 = ifB (< 0) negate id                -- abs++-}