lub 0.0.6 → 0.1.1
raw patch · 3 files changed
+166/−3 lines, 3 filesdep ~unambPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: unamb
API changes (from Hackage documentation)
+ Data.Glb: class HasGlb a
+ Data.Glb: flatGlb :: (Eq a) => a -> a -> a
+ Data.Glb: glb :: (HasGlb a) => a -> a -> a
+ Data.Glb: glbBottom :: String -> a
+ Data.Glb: glbs :: (HasGlb a) => [a] -> a
+ Data.Glb: instance (HasGlb a) => HasGlb (Maybe a)
+ Data.Glb: instance (HasGlb a) => HasGlb [a]
+ 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 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.Lazier: condL :: (HasLub a, HasGlb a) => a -> a -> Bool -> a
+ Data.Lazier: eitherL :: (HasLub c, HasGlb c) => (a -> c) -> (b -> c) -> (Either a b -> c)
Files
- lub.cabal +7/−3
- src/Data/Glb.hs +92/−0
- src/Data/Lazier.hs +67/−0
lub.cabal view
@@ -1,7 +1,7 @@ Name: lub-Version: 0.0.6+Version: 0.1.1 Cabal-Version: >= 1.2-Synopsis: least upper bounds -- information merging+Synopsis: information operators: least upper bound (lub) and greatest lower bound (glb) Category: Concurrency, Data, Other Description: Lub is an experiment in computing least upper information bounds on@@ -11,6 +11,8 @@ neither is bottom, 'lub' is able to synthesize a value from the partial information contained in both of its arguments. .+ This module also defines 'glb', which intersects information.+ . Project wiki page: <http://haskell.org/haskellwiki/lub> . © 2008 by Conal Elliott; BSD3 license.@@ -26,10 +28,12 @@ Library hs-Source-Dirs: src Extensions:- Build-Depends: base < 5, unamb >= 0.1.3+ Build-Depends: base < 5, unamb >= 0.2.4 Exposed-Modules: Data.Repr Data.Lub+ Data.Glb+ Data.Lazier ghc-options: -Wall
+ src/Data/Glb.hs view
@@ -0,0 +1,92 @@+-- {-# LANGUAGE #-}+{-# OPTIONS_GHC -Wall #-}+----------------------------------------------------------------------+-- |+-- Module : Data.Glb+-- Copyright : (c) Conal Elliott 2010+-- License : BSD3+-- +-- Maintainer : conal@conal.net+-- Stability : experimental+-- +-- Greatest lower bound+----------------------------------------------------------------------++module Data.Glb (HasGlb(..),glbBottom,flatGlb) where++import Control.Applicative (liftA2)++import Data.Repr++-- | Types that support information intersection ('glb')+class HasGlb a where+ -- | Greatest lower information bound. Intersects information available+ -- from each argument.+ glb :: a -> a -> a+ -- | n-ary 'lub'. Defaults to @foldr lub undefined@+ glbs :: [a] -> a+ glbs = foldr glb undefined++-- | Bottom for a 'glb'. In the form of @error \"glb: bottom (\<reason\>)\"@,+-- though not really an error.+glbBottom :: String -> a+glbBottom msg = error $ "glb: bottom (" ++ msg ++ ")"++-- | 'glb' on flat types with equality. Gives bottom for unequal+-- arguments.+flatGlb :: Eq a => a -> a -> a+flatGlb a b | a == b = a+ | 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 a, HasGlb b) => HasGlb (a,b) where+ (a,b) `glb` (a',b') = (a `glb` a', b `glb` b')++instance HasGlb b => HasGlb (a -> b) where+ glb = liftA2 glb++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 "glb: bottom (Left/Right mismatch)"+++-- 'glb' on representations+repGlb :: (HasRepr a v, HasGlb v) => a -> a -> a+repGlb = onRepr2 glb++-- instance (HasRepr t v, HasGlb v) => HasGlb t where+-- glb = repGlb++-- For instance,+instance HasGlb a => HasGlb (Maybe a) where glb = repGlb+instance HasGlb a => HasGlb [a] where glb = repGlb++{- -- Examples++-- It takes care to check that some of these examples are computed+-- correctly, since printing stops at the first error. For instance, ask+-- for t5!!1 .++t1,t2 :: Int+t1 = 6 `glb` 8 -- _|_+t2 = 7 `glb` 7 -- 7++t3,t4 :: (Int,Int)+t3 = (3,4) `glb` (4,5) -- (_|_,_|_)+t4 = (3,4) `glb` (3,5) -- (3,_|_)++t5 :: [Int]+t5 = [2,3,5] `glb` [1,3] -- _|_:3:_|_++-}+
+ src/Data/Lazier.hs view
@@ -0,0 +1,67 @@+-- {-# LANGUAGE #-}+{-# OPTIONS_GHC -Wall #-}+----------------------------------------------------------------------+-- |+-- Module : Data.Lazier+-- Copyright : (c) Conal Elliott 2010+-- License : BSD3+-- +-- Maintainer : conal@conal.net+-- Stability : experimental+-- +-- Some lazier operations.+-- See <http://conal.net/blog/posts/lazier-functional-programming-part-2/>+----------------------------------------------------------------------++module Data.Lazier (eitherL,condL) where++import Data.Lub+import Data.Glb++condL :: (HasLub a, HasGlb a) =>+ a -> a -> Bool -> a+condL a b = const (a `glb` b) `lub` (\ c -> if c then a else b)++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++{- -- Examples:++-- It takes care to check that some of these examples are computed+-- correctly, since printing stops at the first error. For instance, ask+-- for t5!!1 .++q :: Int+q = undefined `unamb` 5++t0 :: Int+t0 = condL 3 4 True++t1,t2 :: Int+t1 = condL 6 8 undefined -- _|_+t2 = condL 7 7 undefined -- 7++t3,t4 :: (Int,Int)+t3 = condL (3,4) (4,5) undefined -- (_|_,_|_)+t4 = condL (3,4) (3,5) undefined -- (3,_|_)++t5 :: [Int]+t5 = condL [2,3,5] [1,3] undefined -- _|_:3:_|_+++fe1 :: Either Float Bool -> (Int,String)+fe1 = eitherL (\ x -> (3,"beetle " ++ show x)) (\ b -> (3,"battle " ++ show b))++s1 :: (Int,String)+s1 = fe1 undefined+-- (3,"b*** Exception: glb: bottom (flat & unequal)++s2 :: String+s2 = (tail.tail.tail.snd) (fe1 undefined)+-- "tle *** Exception: Prelude.undefined++s3 :: (Int,String)+s3 = fe1 (Left pi)++-}