packages feed

lub 0.1.7 → 0.1.8

raw patch · 5 files changed

+431/−106 lines, 5 filesdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.Glb: instance (HasGlb a, HasGlb b) => HasGlb (Either a b)
- Data.Glb: instance (HasGlb a, HasGlb b) => HasGlb (a, b)
- Data.Glb: instance HasGlb ()
- Data.Glb: instance HasGlb Bool
- Data.Glb: instance HasGlb Char
- Data.Glb: instance HasGlb Double
- Data.Glb: instance HasGlb Float
- Data.Glb: instance HasGlb Int
- Data.Glb: instance HasGlb Integer
- Data.Glb: instance HasGlb a => HasGlb (Maybe a)
- Data.Glb: instance HasGlb a => HasGlb [a]
- Data.Glb: instance HasGlb b => HasGlb (a -> b)
- Data.Lub: instance (HasLub a, HasLub b) => HasLub (Either a b)
- Data.Lub: instance (HasLub a, HasLub b) => HasLub (a, b)
- Data.Lub: instance HasLub ()
- Data.Lub: instance HasLub Bool
- Data.Lub: instance HasLub Char
- Data.Lub: instance HasLub Double
- Data.Lub: instance HasLub Float
- Data.Lub: instance HasLub Int
- Data.Lub: instance HasLub Integer
- Data.Lub: instance HasLub a => HasLub (Maybe a)
- Data.Lub: instance HasLub a => HasLub [a]
- Data.Lub: instance HasLub b => HasLub (a -> b)
- Data.Repr: instance HasRepr (Maybe a) (Either () a)
- Data.Repr: instance HasRepr [a] (Either () (a, [a]))
+ Data.Glb: class GHasGlb f
+ Data.Glb: genericGlb :: (Generic a, GHasGlb (Rep a)) => a -> a -> a
+ Data.Glb: instance (Data.Glb.HasGlb a, Data.Glb.HasGlb b) => Data.Glb.HasGlb (Data.Either.Either a b)
+ Data.Glb: instance (Data.Glb.HasGlb a, Data.Glb.HasGlb b) => Data.Glb.HasGlb (a, b)
+ Data.Glb: instance (Data.Glb.HasGlb a, Data.Glb.HasGlb b, Data.Glb.HasGlb c) => Data.Glb.HasGlb (a, b, c)
+ Data.Glb: instance (Data.Glb.HasGlb a, Data.Glb.HasGlb b, Data.Glb.HasGlb c, Data.Glb.HasGlb d) => Data.Glb.HasGlb (a, b, c, d)
+ Data.Glb: instance (Data.Glb.HasGlb a, Data.Glb.HasGlb b, Data.Glb.HasGlb c, Data.Glb.HasGlb d, Data.Glb.HasGlb e) => Data.Glb.HasGlb (a, b, c, d, e)
+ Data.Glb: instance Data.Glb.GHasGlb' GHC.Generics.U1
+ Data.Glb: instance Data.Glb.GHasGlb' GHC.Generics.V1
+ Data.Glb: instance Data.Glb.GHasGlb' f => Data.Glb.GHasGlb (GHC.Generics.D1 ('GHC.Generics.MetaData _q _r _s 'GHC.Types.False) f)
+ Data.Glb: instance Data.Glb.HasGlb ()
+ Data.Glb: instance Data.Glb.HasGlb Data.Typeable.TypeRep
+ Data.Glb: instance Data.Glb.HasGlb Data.Void.Void
+ Data.Glb: instance Data.Glb.HasGlb GHC.Integer.Type.Integer
+ Data.Glb: instance Data.Glb.HasGlb GHC.Types.Bool
+ Data.Glb: instance Data.Glb.HasGlb GHC.Types.Char
+ Data.Glb: instance Data.Glb.HasGlb GHC.Types.Double
+ Data.Glb: instance Data.Glb.HasGlb GHC.Types.Float
+ Data.Glb: instance Data.Glb.HasGlb GHC.Types.Int
+ Data.Glb: instance Data.Glb.HasGlb GHC.Types.Ordering
+ Data.Glb: instance Data.Glb.HasGlb a => Data.Glb.HasGlb (Control.Applicative.ZipList a)
+ Data.Glb: instance Data.Glb.HasGlb a => Data.Glb.HasGlb (Data.Functor.Identity.Identity a)
+ Data.Glb: instance Data.Glb.HasGlb a => Data.Glb.HasGlb (Data.Glb.Glb a)
+ Data.Glb: instance Data.Glb.HasGlb a => Data.Glb.HasGlb (GHC.Maybe.Maybe a)
+ Data.Glb: instance Data.Glb.HasGlb a => Data.Glb.HasGlb [a]
+ Data.Glb: instance Data.Glb.HasGlb a => GHC.Base.Semigroup (Data.Glb.Glb a)
+ Data.Glb: instance Data.Glb.HasGlb b => Data.Glb.HasGlb (a -> b)
+ Data.Glb: instance Data.Glb.HasGlb c => Data.Glb.GHasGlb' (GHC.Generics.K1 i c)
+ Data.Glb: instance Data.Glb.HasGlb x => Data.Glb.GHasGlb (GHC.Generics.D1 ('GHC.Generics.MetaData _q _r _s 'GHC.Types.True) (GHC.Generics.C1 _t (GHC.Generics.S1 _u (GHC.Generics.K1 _v x))))
+ Data.Glb: instance GHC.Base.Applicative Data.Glb.Glb
+ Data.Glb: instance GHC.Base.Functor Data.Glb.Glb
+ Data.Glb: instance GHC.Base.Monad Data.Glb.Glb
+ Data.Glb: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Glb.Glb a)
+ Data.Glb: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Glb.Glb a)
+ Data.Glb: instance GHC.Generics.Generic (Data.Glb.Glb a)
+ Data.Glb: instance GHC.Read.Read a => GHC.Read.Read (Data.Glb.Glb a)
+ Data.Glb: instance GHC.Show.Show a => GHC.Show.Show (Data.Glb.Glb a)
+ Data.Glb: instance forall k (a :: k) (b :: k). Data.Glb.HasGlb (a Data.Type.Equality.:~: b)
+ Data.Glb: instance forall k (a :: k). Data.Glb.HasGlb (Data.Proxy.Proxy a)
+ Data.Glb: instance forall k (a :: k). Data.Glb.HasGlb (Data.Typeable.Internal.TypeRep a)
+ Data.Glb: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Data.Glb.HasGlb (f a), Data.Glb.HasGlb (g a)) => Data.Glb.HasGlb ((GHC.Generics.:*:) f g a)
+ Data.Glb: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Data.Glb.HasGlb (f a), Data.Glb.HasGlb (g a)) => Data.Glb.HasGlb ((GHC.Generics.:+:) f g a)
+ Data.Glb: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Data.Glb.HasGlb (f a), Data.Glb.HasGlb (g a)) => Data.Glb.HasGlb (Data.Functor.Product.Product f g a)
+ Data.Glb: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Data.Glb.HasGlb (f a), Data.Glb.HasGlb (g a)) => Data.Glb.HasGlb (Data.Functor.Sum.Sum f g a)
+ Data.Glb: instance forall k (f :: k -> *) (g :: k -> *). (Data.Glb.GHasGlb' f, Data.Glb.GHasGlb' g) => Data.Glb.GHasGlb' (f GHC.Generics.:*: g)
+ Data.Glb: instance forall k (f :: k -> *) (g :: k -> *). (Data.Glb.GHasGlb' f, Data.Glb.GHasGlb' g, Data.Glb.HasCon f, Data.Glb.HasCon g) => Data.Glb.GHasGlb' (f GHC.Generics.:+: g)
+ Data.Glb: instance forall k (f :: k -> *) (g :: k -> *). (Data.Glb.HasCon f, Data.Glb.HasCon g) => Data.Glb.HasCon (f GHC.Generics.:+: g)
+ Data.Glb: instance forall k (f :: k -> *) i (c :: GHC.Generics.Meta). Data.Glb.GHasGlb' f => Data.Glb.GHasGlb' (GHC.Generics.M1 i c f)
+ Data.Glb: instance forall k (i :: GHC.Generics.Meta) (f :: k -> *). GHC.Generics.Constructor i => Data.Glb.HasCon (GHC.Generics.C1 i f)
+ Data.Glb: instance forall k a (b :: k). Data.Glb.HasGlb a => Data.Glb.HasGlb (Data.Functor.Const.Const a b)
+ Data.Glb: instance forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1). Data.Glb.HasGlb (f (g a)) => Data.Glb.HasGlb (Data.Functor.Compose.Compose f g a)
+ Data.Glb: instance forall k1 k2 (a :: k1) (b :: k2). Data.Glb.HasGlb (a Data.Type.Equality.:~~: b)
+ Data.Laxer: fairZip :: [a] -> [b] -> [(a, b)]
+ Data.Laxer: fairZipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
+ Data.Laxer: foldrL :: (HasLub b, HasGlb b) => (a -> b -> b) -> b -> [a] -> b
+ Data.Laxer: maybeL :: (HasLub b, HasGlb b) => b -> (a -> b) -> Maybe a -> b
+ Data.Lub: Lub :: a -> Lub a
+ Data.Lub: [getLub] :: Lub a -> a
+ Data.Lub: class GHasLub f
+ Data.Lub: genericLub :: (Generic a, GHasLub (Rep a)) => a -> a -> a
+ Data.Lub: instance (Data.Lub.HasLub a, Data.Lub.HasLub b) => Data.Lub.HasLub (Data.Either.Either a b)
+ Data.Lub: instance (Data.Lub.HasLub a, Data.Lub.HasLub b) => Data.Lub.HasLub (a, b)
+ Data.Lub: instance (Data.Lub.HasLub a, Data.Lub.HasLub b, Data.Lub.HasLub c) => Data.Lub.HasLub (a, b, c)
+ Data.Lub: instance (Data.Lub.HasLub a, Data.Lub.HasLub b, Data.Lub.HasLub c, Data.Lub.HasLub d) => Data.Lub.HasLub (a, b, c, d)
+ Data.Lub: instance (Data.Lub.HasLub a, Data.Lub.HasLub b, Data.Lub.HasLub c, Data.Lub.HasLub d, Data.Lub.HasLub e) => Data.Lub.HasLub (a, b, c, d, e)
+ Data.Lub: instance Data.Lub.GHasLub' GHC.Generics.U1
+ Data.Lub: instance Data.Lub.GHasLub' GHC.Generics.V1
+ Data.Lub: instance Data.Lub.GHasLub' f => Data.Lub.GHasLub (GHC.Generics.D1 ('GHC.Generics.MetaData _q _r _s 'GHC.Types.False) f)
+ Data.Lub: instance Data.Lub.HasLub ()
+ Data.Lub: instance Data.Lub.HasLub Data.Typeable.TypeRep
+ Data.Lub: instance Data.Lub.HasLub Data.Void.Void
+ Data.Lub: instance Data.Lub.HasLub GHC.Integer.Type.Integer
+ Data.Lub: instance Data.Lub.HasLub GHC.Types.Bool
+ Data.Lub: instance Data.Lub.HasLub GHC.Types.Char
+ Data.Lub: instance Data.Lub.HasLub GHC.Types.Double
+ Data.Lub: instance Data.Lub.HasLub GHC.Types.Float
+ Data.Lub: instance Data.Lub.HasLub GHC.Types.Int
+ Data.Lub: instance Data.Lub.HasLub GHC.Types.Ordering
+ Data.Lub: instance Data.Lub.HasLub a => Data.Lub.HasLub (Control.Applicative.ZipList a)
+ Data.Lub: instance Data.Lub.HasLub a => Data.Lub.HasLub (Data.Functor.Identity.Identity a)
+ Data.Lub: instance Data.Lub.HasLub a => Data.Lub.HasLub (Data.Lub.Lub a)
+ Data.Lub: instance Data.Lub.HasLub a => Data.Lub.HasLub (GHC.Maybe.Maybe a)
+ Data.Lub: instance Data.Lub.HasLub a => Data.Lub.HasLub [a]
+ Data.Lub: instance Data.Lub.HasLub a => GHC.Base.Monoid (Data.Lub.Lub a)
+ Data.Lub: instance Data.Lub.HasLub a => GHC.Base.Semigroup (Data.Lub.Lub a)
+ Data.Lub: instance Data.Lub.HasLub b => Data.Lub.HasLub (a -> b)
+ Data.Lub: instance Data.Lub.HasLub c => Data.Lub.GHasLub' (GHC.Generics.K1 i c)
+ Data.Lub: instance Data.Lub.HasLub x => Data.Lub.GHasLub (GHC.Generics.D1 ('GHC.Generics.MetaData _q _r _s 'GHC.Types.True) (GHC.Generics.C1 _t (GHC.Generics.S1 _u (GHC.Generics.K1 _v x))))
+ Data.Lub: instance GHC.Base.Applicative Data.Lub.Lub
+ Data.Lub: instance GHC.Base.Functor Data.Lub.Lub
+ Data.Lub: instance GHC.Base.Monad Data.Lub.Lub
+ Data.Lub: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Lub.Lub a)
+ Data.Lub: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Lub.Lub a)
+ Data.Lub: instance GHC.Generics.Generic (Data.Lub.Lub a)
+ Data.Lub: instance GHC.Read.Read a => GHC.Read.Read (Data.Lub.Lub a)
+ Data.Lub: instance GHC.Show.Show a => GHC.Show.Show (Data.Lub.Lub a)
+ Data.Lub: instance forall k (a :: k) (b :: k). Data.Lub.HasLub (a Data.Type.Equality.:~: b)
+ Data.Lub: instance forall k (a :: k). Data.Lub.HasLub (Data.Typeable.Internal.TypeRep a)
+ Data.Lub: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Data.Lub.HasLub (f a), Data.Lub.HasLub (g a)) => Data.Lub.HasLub ((GHC.Generics.:*:) f g a)
+ Data.Lub: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Data.Lub.HasLub (f a), Data.Lub.HasLub (g a)) => Data.Lub.HasLub ((GHC.Generics.:+:) f g a)
+ Data.Lub: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Data.Lub.HasLub (f a), Data.Lub.HasLub (g a)) => Data.Lub.HasLub (Data.Functor.Product.Product f g a)
+ Data.Lub: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Data.Lub.HasLub (f a), Data.Lub.HasLub (g a)) => Data.Lub.HasLub (Data.Functor.Sum.Sum f g a)
+ Data.Lub: instance forall k (f :: k -> *) (g :: k -> *). (Data.Lub.GHasLub' f, Data.Lub.GHasLub' g) => Data.Lub.GHasLub' (f GHC.Generics.:*: g)
+ Data.Lub: instance forall k (f :: k -> *) (g :: k -> *). (Data.Lub.GHasLub' f, Data.Lub.GHasLub' g) => Data.Lub.GHasLub' (f GHC.Generics.:+: g)
+ Data.Lub: instance forall k (f :: k -> *) i (c :: GHC.Generics.Meta). Data.Lub.GHasLub' f => Data.Lub.GHasLub' (GHC.Generics.M1 i c f)
+ Data.Lub: instance forall k (t :: k). Data.Lub.HasLub (Data.Proxy.Proxy t)
+ Data.Lub: instance forall k a (b :: k). Data.Lub.HasLub a => Data.Lub.HasLub (Data.Functor.Const.Const a b)
+ Data.Lub: instance forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1). Data.Lub.HasLub (f (g a)) => Data.Lub.HasLub (Data.Functor.Compose.Compose f g a)
+ Data.Lub: instance forall k1 k2 (a :: k1) (b :: k2). Data.Lub.HasLub (a Data.Type.Equality.:~~: b)
+ Data.Lub: newtype Lub a
+ Data.Repr: instance Data.Repr.HasRepr (GHC.Maybe.Maybe a) (Data.Either.Either () a)
+ Data.Repr: instance Data.Repr.HasRepr [a] (Data.Either.Either () (a, [a]))
- Data.Glb: class HasGlb a where glbs1 = foldr1 glb
+ Data.Glb: class HasGlb a
- Data.Glb: glb :: HasGlb a => a -> a -> a
+ Data.Glb: glb :: (HasGlb a, Generic a, GHasGlb (Rep a)) => a -> a -> a
- Data.Laxer: eitherL :: (HasLub c, HasGlb c) => (a -> c) -> (b -> c) -> (Either a b -> c)
+ Data.Laxer: eitherL :: (HasLub c, HasGlb c) => (a -> c) -> (b -> c) -> Either a b -> c
- Data.Lub: class HasLub a where lubs = foldr lub undefined
+ Data.Lub: class HasLub a
- Data.Lub: lub :: HasLub a => a -> a -> a
+ Data.Lub: lub :: (HasLub a, Generic a, GHasLub (Rep a)) => a -> a -> a
- Data.Lub: parCommute :: HasLub b => (a -> a -> b) -> (a -> a -> b)
+ Data.Lub: parCommute :: HasLub b => (a -> a -> b) -> a -> a -> b
- Data.Repr: onRepr :: (HasRepr a ra, HasRepr b rb) => (ra -> rb) -> (a -> b)
+ Data.Repr: onRepr :: (HasRepr a ra, HasRepr b rb) => (ra -> rb) -> a -> b
- Data.Repr: onRepr2 :: (HasRepr a ra, HasRepr b rb, HasRepr c rc) => (ra -> rb -> rc) -> (a -> b -> c)
+ Data.Repr: onRepr2 :: (HasRepr a ra, HasRepr b rb, HasRepr c rc) => (ra -> rb -> rc) -> a -> b -> c

Files

lub.cabal view
@@ -1,6 +1,6 @@ Name:                lub-Version:             0.1.7-Cabal-Version:       >= 1.2+Version:             0.1.8+Cabal-Version:       >= 1.10 Synopsis:            information operators: least upper bound (lub) and greatest lower bound (glb) Category:            Concurrency, Data, Other Description:@@ -15,20 +15,25 @@   .   Project wiki page: <http://haskell.org/haskellwiki/lub>   .-  &#169; 2008 by Conal Elliott; BSD3 license.+  &#169; 2008-2014 by Conal Elliott; BSD3 license. Author:              Conal Elliott  Maintainer:          conal@conal.net Homepage:            http://haskell.org/haskellwiki/lub Package-Url:         http://code.haskell.org/~conal/code/lub-Copyright:           (c) 2008,2009,2010 by Conal Elliott+Copyright:           (c) 2008-2014 by Conal Elliott License:             BSD3 Stability:           experimental build-type:          Simple +source-repository head+  type:     git+  location: git://github.com/conal/lub.git+ Library+  default-language:    Haskell2010   hs-Source-Dirs:      src   Extensions:-  Build-Depends:       base < 5, unamb >= 0.2.4+  Build-Depends:       base >= 4.6 && < 5, unamb >= 0.2.4   Exposed-Modules:                             Data.Repr                        Data.Lub
src/Data/Glb.hs view
@@ -1,4 +1,18 @@--- {-# LANGUAGE #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PatternGuards #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+#if __GLASGOW_HASKELL__ >= 708+{-# LANGUAGE EmptyCase #-}+{-# LANGUAGE PolyKinds #-}+#endif+ {-# OPTIONS_GHC -Wall #-} ---------------------------------------------------------------------- -- |@@ -12,22 +26,69 @@ -- Greatest lower bound ---------------------------------------------------------------------- -module Data.Glb (HasGlb(..),glbBottom,flatGlb) where+module Data.Glb (HasGlb(..),glbBottom,flatGlb+  , GHasGlb+  , genericGlb+  ) where -import Control.Applicative (liftA2)+import Control.Applicative (liftA2, Const, ZipList) -import Data.Repr+import GHC.Generics+import qualified Data.Typeable as Typeable+#if MIN_VERSION_base(4,7,0)+import Data.Type.Equality ((:~:))+import qualified Data.Proxy as Proxy+#endif+#if MIN_VERSION_base(4,8,0)+import qualified Data.Functor.Identity as Identity+import qualified Data.Void as Void+#endif+#if MIN_VERSION_base(4,9,0)+import qualified Data.Functor.Compose as Compose+import qualified Data.Functor.Product as Product+import qualified Data.Functor.Sum as Sum+import qualified Data.Semigroup as Semigroup+#endif+#if MIN_VERSION_base(4,10,0)+import Data.Type.Equality ((:~~:))+import qualified Type.Reflection as TR+#endif + -- | Types that support information intersection ('glb') class HasGlb a where   -- | Greatest lower information bound.  Intersects information available   -- from each argument.   glb  :: a -> a -> a+  default glb :: (Generic a, GHasGlb (Rep a)) => a -> a -> a+  glb = genericGlb+   -- | n-ary 'glb' for n > 0.  Defaults to @foldr1 glb@.  Unlike @lub@, we   -- have no unit for 'glb'.   glbs1 :: [a] -> a   glbs1 = foldr1 glb +-- | The 'Semigroup.Semigroup' operation takes the+-- greatest lower bound.+newtype Glb a = Glb { getGlb :: a }+  deriving (Show, Read, Eq, Ord, Generic)++instance HasGlb a => HasGlb (Glb a)++#if MIN_VERSION_base(4,9,0)+instance HasGlb a => Semigroup.Semigroup (Glb a) where+  Glb a <> Glb b = Glb (a `glb` b)+  stimes = Semigroup.stimesIdempotent+#endif++instance Functor Glb where+  fmap f (Glb a) = Glb (f a)+instance Applicative Glb where+  pure = Glb+  Glb f <*> Glb a = Glb (f a)+instance Monad Glb where+  Glb a >>= f = f a+ -- | Bottom for a 'glb'.  In the form of @error \"glb: bottom (\<reason\>)\"@, -- though not really an error. glbBottom :: String -> a@@ -40,38 +101,62 @@             | otherwise = glbBottom "flat & unequal"  -- Flat types:-instance HasGlb ()      where glb = flatGlb-instance HasGlb Bool    where glb = flatGlb instance HasGlb Char    where glb = flatGlb instance HasGlb Int     where glb = flatGlb instance HasGlb Integer where glb = flatGlb instance HasGlb Float   where glb = flatGlb instance HasGlb Double  where glb = flatGlb+instance HasGlb Typeable.TypeRep where glb = flatGlb+#if MIN_VERSION_base(4,7,0)+instance HasGlb (a :~: b) where glb = flatGlb+#endif+#if MIN_VERSION_base(4,10,0)+instance HasGlb (a :~~: b) where glb = flatGlb+instance HasGlb (TR.TypeRep a) where glb = flatGlb+#endif+ -- ... -instance (HasGlb a, HasGlb b) => HasGlb (a,b) where-  (a,b) `glb` (a',b') = (a `glb` a', b `glb` b')+-- Generic-derived instances+instance HasGlb ()+#if MIN_VERSION_base(4,7,0)+instance HasGlb (Proxy.Proxy a)+#endif+instance HasGlb Bool+instance HasGlb Ordering+instance (HasGlb a, HasGlb b) => HasGlb (Either a b)+instance HasGlb a => HasGlb (Maybe a)+instance HasGlb a => HasGlb [a]+instance HasGlb a => HasGlb (ZipList a) -instance HasGlb b => HasGlb (a -> b) where-  glb = liftA2 glb+instance (HasGlb a, HasGlb b) => HasGlb (a, b)+instance (HasGlb a, HasGlb b, HasGlb c) => HasGlb (a, b, c)+instance (HasGlb a, HasGlb b, HasGlb c, HasGlb d) => HasGlb (a, b, c, d)+instance (HasGlb a, HasGlb b, HasGlb c, HasGlb d, HasGlb e) => HasGlb (a, b, c, d, e) -instance (HasGlb a, HasGlb b) => HasGlb (Either a b) where-  Left  a `glb` Left  a' = Left  (a `glb` a')-  Right b `glb` Right b' = Right (b `glb` b')-  _ `glb` _ = glbBottom "Left/Right mismatch"+instance HasGlb a => HasGlb (Const a b) +#if MIN_VERSION_base(4,8,0)+instance HasGlb a => HasGlb (Identity.Identity a)+instance HasGlb Void.Void+#endif --- 'glb' on representations-repGlb :: (HasRepr a v, HasGlb v) => a -> a -> a-repGlb = onRepr2 glb+-- People often use :+: and :*: rather than Sum and Product+-- even outside of a Generic context.+instance (HasGlb (f a), HasGlb (g a)) => HasGlb ((f :*: g) a)+instance (HasGlb (f a), HasGlb (g a)) => HasGlb ((f :+: g) a) --- instance (HasRepr t v, HasGlb v) => HasGlb t where---   glb = repGlb+#if MIN_VERSION_base(4,9,0)+instance HasGlb (f (g a)) => HasGlb (Compose.Compose f g a)+instance (HasGlb (f a), HasGlb (g a)) => HasGlb (Product.Product f g a)+instance (HasGlb (f a), HasGlb (g a)) => HasGlb (Sum.Sum f g a)+#endif --- For instance,-instance HasGlb a => HasGlb (Maybe a) where glb = repGlb-instance HasGlb a => HasGlb [a]       where glb = repGlb +-- Functions+instance HasGlb b => HasGlb (a -> b) where+  glb = liftA2 glb+ {- -- Examples  -- It takes care to check that some of these examples are computed@@ -91,3 +176,76 @@  -} +-- | Used for generic deriving of 'HasGlb'+class GHasGlb f where+  gglb :: (Generic a, Rep a ~ f) => a -> a -> a++-- | A suitable definition of 'glb' for instances of 'Generic'.+genericGlb :: (Generic a, GHasGlb (Rep a)) => a -> a -> a+-- What makes genericGlb different from gglb? When using+-- TypeApplications, the first type argument of gglb is+-- the representation type; that's not very friendly.+genericGlb a b = gglb a b++-- Newtypes don't want their outsides forced/checked, because they don't have any.+instance HasGlb x => GHasGlb (D1 ('MetaData _q _r _s 'True) (C1 _t (S1 _u (K1 _v x)))) where+  gglb a b+    | M1 (M1 (M1 (K1 x))) <- from a+    , M1 (M1 (M1 (K1 y))) <- from b+    = to (M1 (M1 (M1 (K1 (glb x y)))))++-- Not a newtype, but possibly a lifted unary tuple.+-- We force the outsides first in case that is so.+instance GHasGlb' f => GHasGlb (D1 ('MetaData _q _r _s 'False) f) where+  gglb !a !b+    = to (M1 (gglb' ar br))+    where+      M1 ar = from a+      M1 br = from b++-- | Used for non-newtype 'Generic' deriving.+class GHasGlb' f where+  gglb' :: f p -> f p -> f p++instance GHasGlb' f => GHasGlb' (M1 i c f) where+  gglb' (M1 l) (M1 r) = M1 (gglb' l r)++instance (GHasGlb' f, GHasGlb' g, HasCon f, HasCon g) => GHasGlb' (f :+: g) where+  gglb' (L1 l1) (L1 l2) = L1 (gglb' l1 l2)+  gglb' (R1 r1) (R1 r2) = R1 (gglb' r1 r2)++  gglb' (L1 l1) (R1 r2) = mismatchedCons (getConName l1) (getConName r2)+  gglb' (R1 r1) (L1 l2) = mismatchedCons (getConName r1) (getConName l2)++class HasCon f where+  getConName :: f p -> String+instance Constructor i => HasCon (C1 i f) where+  getConName = conName+instance (HasCon f, HasCon g) => HasCon (f :+: g) where+  getConName (L1 x) = getConName x+  getConName (R1 x) = getConName x++mismatchedCons :: String -> String -> a+mismatchedCons l r = glbBottom $+    "Mismatched constructors.\nThe left argument was built with "+    ++ l ++ ",\nbut the right one was built with " ++ r ++ "."++instance (GHasGlb' f, GHasGlb' g) => GHasGlb' (f :*: g) where+  gglb' (l1 :*: l2) (r1 :*: r2) =+    gglb' l1 r1 :*: gglb' l2 r2++instance GHasGlb' U1 where+  -- We pattern match strictly so we don't get+  --+  -- glb @() () undefined = ()+  gglb' U1 U1 = U1++instance GHasGlb' V1 where+#if __GLASGOW_HASKELL__ >= 708+  gglb' v _ = case v of+#else+  gglb' !_ _ = error "Can't happen"+#endif++instance HasGlb c => GHasGlb' (K1 i c) where+  gglb' (K1 l) (K1 r) = K1 $ glb l r
src/Data/Laxer.hs view
@@ -13,12 +13,17 @@ -- See <http://conal.net/blog/posts/lazier-functional-programming-part-2/> ---------------------------------------------------------------------- -module Data.Laxer (eitherL,condL) where+module Data.Laxer (eitherL,condL,foldrL,maybeL,fairZipWith, fairZip) where  import Data.Lub import Data.Glb --- | Laxer if-then-else, due to Luke Palmer+-- | Laxer if-then-else, due to Luke Palmer.+--+-- @+-- condL a a undefined = a+-- condL (Left 3) (Left undefined) undefined = Left undefined+-- @ condL :: (HasLub a, HasGlb a) =>          a -> a -> Bool -> a condL a b = const (a `glb` b) `lub` (\ c -> if c then a else b)@@ -27,6 +32,40 @@ eitherL :: (HasLub c, HasGlb c) =>            (a -> c) -> (b -> c) -> (Either a b -> c) eitherL f g = const (f undefined `glb` g undefined) `lub` either f g++-- | Laxer variant of 'maybe'+maybeL :: (HasLub b, HasGlb b) =>+           b -> (a -> b) -> (Maybe a -> b)+maybeL n j = const (n `glb` j undefined) `lub` maybe n j++-- | Laxer variant of 'foldr' for lists+foldrL :: (HasLub b, HasGlb b) => (a -> b -> b) -> b -> [a] -> b+foldrL c n = const fallback `lub` go+  where+    fallback = n `glb` c undefined undefined+    go [] = n+    go (x : xs) = c x $ fallback `lub` go xs++-- | A version of 'zipWith' that succeeds if either list+-- ends at the same time the other one bottoms out.+--+-- Laws:+--+-- > fairZipWith >= zipWith+-- > flip . fairZipWith = fairZipWith . flip+fairZipWith :: (a -> b -> c) -> [a] -> [b] -> [c]+fairZipWith f as bs =+  zipWith3+    (const f)+    (lub (zipWith discard as bs) (zipWith discard bs as))+    as+    bs+  where+    discard _ _ = ()++-- | @fairZip = fairZipWith (,)@+fairZip :: [a] -> [b] -> [(a, b)]+fairZip = fairZipWith (,)  {- -- Examples: 
src/Data/Lub.hs view
@@ -1,5 +1,17 @@-{-# LANGUAGE TypeFamilies, FlexibleContexts #-}--- {-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PatternGuards #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+#if __GLASGOW_HASKELL__ >= 708+{-# LANGUAGE EmptyCase #-}+{-# LANGUAGE PolyKinds #-} -- For instances+#endif {-# OPTIONS_GHC -Wall #-} ---------------------------------------------------------------------- -- |@@ -19,17 +31,39 @@ module Data.Lub   (    -- * Least upper bounds-    HasLub(..), flatLub+    HasLub(..), Lub(..), flatLub   -- * Some useful special applications of 'lub'   , parCommute, ptimes+  -- * Generic deriving+  , GHasLub+  , genericLub   ) where -import Control.Applicative (liftA2)+import Control.Applicative (liftA2, Const, ZipList)  import Data.Unamb hiding (parCommute) -- import qualified Data.Unamb as Unamb -import Data.Repr+import GHC.Generics+import qualified Data.Typeable as Typeable+#if MIN_VERSION_base(4,7,0)+import Data.Type.Equality ((:~:))+import qualified Data.Proxy as Proxy+#endif+#if MIN_VERSION_base(4,8,0)+import qualified Data.Functor.Identity as Identity+import qualified Data.Void as Void+#endif+#if MIN_VERSION_base(4,9,0)+import qualified Data.Functor.Compose as Compose+import qualified Data.Functor.Product as Product+import qualified Data.Functor.Sum as Sum+import qualified Data.Semigroup as Semigroup+#endif+#if MIN_VERSION_base(4,10,0)+import Data.Type.Equality ((:~~:))+import qualified Type.Reflection as TR+#endif  -- | Types that support information merging ('lub') class HasLub a where@@ -37,14 +71,42 @@   -- each argument.  The arguments must be consistent, i.e., must have a   -- common upper bound.   lub  :: a -> a -> a+  default lub :: (Generic a, GHasLub (Rep a)) => a -> a -> a+  lub = genericLub   -- | n-ary 'lub'.  Defaults to @foldr lub undefined@   lubs :: [a] -> a+  -- Why not foldr1 lub? That would be cheaper, because it avoids+  -- a call to `lub` with `undefined`. But it would be too strict:+  -- lubs (3 : undefined) would be undefined when it should be 3.   lubs = foldr lub undefined --- The following instance is wrong, since it lubs two undefineds to ().--- --- instance HasLub () where _ `lub` _ = ()+-- | The 'Semigroup.Semigroup' operation takes the+-- least upper bound.+newtype Lub a = Lub { getLub :: a }+  deriving (Show, Read, Eq, Ord, Generic) +instance HasLub a => HasLub (Lub a)++#if MIN_VERSION_base(4,9,0)+instance HasLub a => Semigroup.Semigroup (Lub a) where+  Lub a <> Lub b = Lub (a `lub` b)+  stimes = Semigroup.stimesIdempotent+#endif++instance HasLub a => Monoid (Lub a) where+  mempty = undefined  -- This is actually the unit for Lub a!+#if !MIN_VERSION_base(4,11,0)+  Lub a `mappend` Lub b = Lub (a `lub` b)+#endif++instance Functor Lub where+  fmap f (Lub a) = Lub (f a)+instance Applicative Lub where+  pure = Lub+  Lub f <*> Lub a = Lub (f a)+instance Monad Lub where+  Lub a >>= f = f a+ -- | A 'lub' for flat domains.  Equivalent to 'unamb'.  Handy for defining -- 'HasLub' instances, e.g., -- @@ -55,89 +117,62 @@ flatLub = unamb  -- Flat types:-instance HasLub ()      where lub = flatLub-instance HasLub Bool    where lub = flatLub instance HasLub Char    where lub = flatLub instance HasLub Int     where lub = flatLub instance HasLub Integer where lub = flatLub instance HasLub Float   where lub = flatLub instance HasLub Double  where lub = flatLub+#if MIN_VERSION_base(4,7,0)+instance HasLub (a :~: b) where lub = flatLub+#endif+#if MIN_VERSION_base(4,10,0)+instance HasLub (a :~~: b) where lub = flatLub+instance HasLub (TR.TypeRep a) where lub = flatLub+#endif+instance HasLub Typeable.TypeRep where lub = flatLub -- ... ---- Lub on pairs--- pairLub :: (HasLub a, HasLub b) =>---            (a,b) -> (a,b) -> (a,b)---- Too strict.  Bottom if one pair is bottom---- instance (HasLub a, HasLub b) => HasLub (a,b) where---   (a,b) `lub` (a',b') = (a `lub` a', b `lub` b')+-- Generic-derived types:+instance HasLub ()+#if MIN_VERSION_base(4,7,0)+instance HasLub (Proxy.Proxy t)+#endif+instance HasLub Bool+instance HasLub Ordering+instance (HasLub a, HasLub b) => HasLub (Either a b)+instance HasLub a => HasLub (Maybe a)+instance HasLub a => HasLub [a]+instance HasLub a => HasLub (ZipList a) --- Too lazy.  Non-bottom even if both pairs are bottom+instance (HasLub a, HasLub b) => HasLub (a,b)+instance (HasLub a, HasLub b, HasLub c) => HasLub (a,b,c)+instance (HasLub a, HasLub b, HasLub c, HasLub d) => HasLub (a,b,c,d)+instance (HasLub a, HasLub b, HasLub c, HasLub d, HasLub e) => HasLub (a,b,c,d,e) --- instance (HasLub a, HasLub b) => HasLub (a,b) where---   ~(a,b) `lub` ~(a',b') = (a `lub` a', b `lub` b')+instance HasLub a => HasLub (Const a b) +#if MIN_VERSION_base(4,8,0)+instance HasLub a => HasLub (Identity.Identity a)+instance HasLub Void.Void+#endif -instance (HasLub a, HasLub b) => HasLub (a,b) where-  ~p@(a,b) `lub` ~p'@(a',b') =-     (definedP p `unamb` definedP p') `seq` (a `lub` a', b `lub` b')+-- People often use :+: and :*: rather than Sum and Product+-- even outside of a Generic context.+instance (HasLub (f a), HasLub (g a)) => HasLub ((f :*: g) a)+instance (HasLub (f a), HasLub (g a)) => HasLub ((f :+: g) a) -definedP :: (a,b) -> Bool-definedP (_,_) = True+#if MIN_VERSION_base(4,9,0)+instance HasLub (f (g a)) => HasLub (Compose.Compose f g a)+instance (HasLub (f a), HasLub (g a)) => HasLub (Product.Product f g a)+instance (HasLub (f a), HasLub (g a)) => HasLub (Sum.Sum f g a)+#endif +-- Functions. This is not *strictly* correct, because it converts `undefined`+-- into `const undefined`, but anyone who cares is doing something fishy+-- anyway. instance HasLub b => HasLub (a -> b) where   lub = liftA2 lub---- f `lub` g = \ a -> f a `lub` g a--instance (HasLub a, HasLub b) => HasLub (Either a b) where-  s `lub` s' = if isL s `unamb` isL s' then-                 Left  (outL s `lub` outL s')-               else-                 Right (outR s `lub` outR s')--isL :: Either a b -> Bool-isL = either (const True) (const False)--outL :: Either a b -> a-outL = either id (error "outL on Right")--outR :: Either a b -> b-outR = either (error "outR on Left") id---- Generic case---   instance (HasRepr t v, HasLub v) => HasLub t where lub = repLub---- 'lub' on representations-repLub :: (HasRepr a v, HasLub v) => a -> a -> a-repLub = onRepr2 lub---- instance (HasRepr t v, HasLub v) => HasLub t where---   lub = repLub---- For instance,-instance HasLub a => HasLub (Maybe a) where lub = repLub-instance HasLub a => HasLub [a]       where lub = repLub------ a `repLub` a' = unrepr (repr a `lub` repr a')----{-  -- Examples:--(undefined,False) `lub` (True,undefined)--(undefined,(undefined,False)) `lub` ((),(undefined,undefined)) `lub` (undefined,(True,undefined))--Left () `lub` undefined :: Either () Bool--[1,undefined,2] `lub` [undefined,3,2]---}+  -- f `lub` g = \ a -> f a `lub` g a  -- | Turn a binary commutative operation into that tries both orders in -- parallel, 'lub'-merging the results.  Useful when there are special@@ -187,4 +222,91 @@ zip' [10,20] (1 : 2 : error "boom") zip' (1 : 2 : error "boom") [10,20] +Alternatively, we can avoid the constraints and partial matches+by using lub only to (lazily) calculate the *length* of the+result. See Data.Laxer.fairZipWith and fairZip. -}++-- ------------------------+-- Generic deriving++-- | Used for generic deriving of 'HasLub'+class GHasLub f where+  -- Yes, this is an unusual type for the method of a class of Generic+  -- representations. But we need to make decisions about what we do with `a`+  -- itself based on what its representation looks like, and this seems+  -- to be the simplest way to achieve that by far.+  glub :: (Generic a, Rep a ~ f) => a -> a -> a++-- | A suitable definition of 'lub' for instances of 'Generic'.+genericLub :: (Generic a, GHasLub (Rep a)) => a -> a -> a+-- What makes genericLub different from glub? When using+-- TypeApplications, the first type argument of glub is+-- the representation type; that's not very friendly.+genericLub a b = glub a b++-- Newtypes don't want their outsides forced/checked, because they don't have any.+instance HasLub x => GHasLub (D1 ('MetaData _q _r _s 'True) (C1 _t (S1 _u (K1 _v x)))) where+  glub a b+    | M1 (M1 (M1 (K1 x))) <- from a+    , M1 (M1 (M1 (K1 y))) <- from b+    = to (M1 (M1 (M1 (K1 (lub x y)))))++-- Not a newtype. First, we use 'unamb' to get the value in WHNF.+-- We can then walk the generic representation of that WHNF value,+-- setting up 'lub' computations using the actual values stored+-- in the (generic representations of) the two argument values.+instance GHasLub' f => GHasLub (D1 ('MetaData _q _r _s 'False) f) where+  -- It turns out to be *really* helpful to use `unamb a b` here rather than+  -- unamb (from a) (from b). Doing so gets us really clean Core without a+  -- bunch of unnecessary generic conversions. Basically, we want to avoid+  -- computing any generic representations within `unamb`, because nothing can+  -- inline through that. An extra side benefit is that we can use the same+  -- GHasLub instance for lifted unary tuples as for other non-newtype types,+  -- which avoids a lot of mess.+  glub a b+    = to (M1 (glub' (unM1 (from ab)) ar br))+    where+      M1 ar = from a+      M1 br = from b+      -- We force ab here in case the type is a lifted unary tuple, in which case+      -- its outside *won't* be forced by glub'.+      !ab = a `unamb` b++-- | Used for non-newtype 'Generic' deriving.+class GHasLub' f where+  -- | The first argument is used to get constructor+  -- info. We are free to pattern match+  -- on it all we like.+  glub' :: f p -> f p -> f p -> f p++instance GHasLub' f => GHasLub' (M1 i c f) where+  glub' (M1 outer) (M1 l) (M1 r) = M1 (glub' outer l r)++instance (GHasLub' f, GHasLub' g) => GHasLub' (f :+: g) where+  glub' (L1 o) ~(L1 l1) ~(L1 l2) = L1 (glub' o l1 l2)+  glub' (R1 o) ~(R1 r1) ~(R1 r2) = R1 (glub' o r1 r2)++instance (GHasLub' f, GHasLub' g) => GHasLub' (f :*: g) where+  -- We must pattern match strictly on the first argument, because+  -- otherwise we'll end up with things like+  --+  --   lub @(a,b) undefined undefined = (undefined, undefined)+  glub' (o1 :*: o2) ~(l1 :*: l2) ~(r1 :*: r2) =+    glub' o1 l1 r1 :*: glub' o2 l2 r2++instance GHasLub' U1 where+  -- We pattern match strictly so we don't get+  --+  -- lub @() undefined undefined = ()+  glub' U1 _ _ = U1++instance GHasLub' V1 where+#if __GLASGOW_HASKELL__ >= 708+  glub' v _ _ = case v of+#else+  glub' !_ _ _ = error "Can't happen"+#endif++instance HasLub c => GHasLub' (K1 i c) where+  glub' _ (K1 l) (K1 r) = K1 $ lub l r
src/Data/Repr.hs view
@@ -16,7 +16,8 @@ -- This version uses associated types for HasRepr ---------------------------------------------------------------------- -module Data.Repr (HasRepr(..), onRepr, onRepr2) where+module Data.Repr {-# DEPRECATED "Use generics instead" #-}+  (HasRepr(..), onRepr, onRepr2) where  -- Reprs.  TODO: find & use a simple, standard generic programming framework.