packages feed

liboleg 2010.1.9.0 → 2010.1.10.0

raw patch · 10 files changed

+546/−8 lines, 10 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Data.Symbolic.Diff: diffC :: (Floating a, Floating b) => Var b -> Code a -> Code a
+ Data.Symbolic.Diff: diff_fn :: (Floating b) => (forall a. (Floating a) => a -> a) -> QCode (b -> b)
+ Data.Symbolic.Diff: instance (Floating a) => Floating (Code a)
+ Data.Symbolic.Diff: instance (Fractional a) => Fractional (Code a)
+ Data.Symbolic.Diff: instance (Num a) => Num (Code a)
+ Data.Symbolic.Diff: show_fn :: (forall a. (Floating a) => a -> a) -> IO ()
+ Data.Symbolic.Diff: simpleC :: (Floating a) => Var b -> Code a -> Code a
+ Data.Symbolic.Diff: simpleCL :: (Floating a) => Var b -> Code a -> Maybe (Code a)
+ Data.Symbolic.Diff: testf1 :: (Num a) => a
+ Data.Symbolic.TypedCode: appC :: Code (a -> b) -> Code a -> Code b
+ Data.Symbolic.TypedCode: data Code a
+ Data.Symbolic.TypedCode: data Var a
+ Data.Symbolic.TypedCode: instance Eq (Code a)
+ Data.Symbolic.TypedCode: instance Show (Code a)
+ Data.Symbolic.TypedCode: integerC :: (Num a) => Integer -> Code a
+ Data.Symbolic.TypedCode: new'diffVar :: Q (Var a)
+ Data.Symbolic.TypedCode: on'1opC :: Code (a -> b) -> Code d -> Maybe (Code a)
+ Data.Symbolic.TypedCode: on'2opC :: Code (a -> b -> c) -> Code d -> Maybe (Code a, Code b)
+ Data.Symbolic.TypedCode: on'litC :: Code a -> Maybe (Code a)
+ Data.Symbolic.TypedCode: on'litRationalC :: Code a -> Maybe Rational
+ Data.Symbolic.TypedCode: on'varC :: Var a -> Code b -> Maybe (Either (Var a) (Var b))
+ Data.Symbolic.TypedCode: op'add :: (Num a) => Code (a -> a -> a)
+ Data.Symbolic.TypedCode: op'cos :: (Floating a) => Code (a -> a)
+ Data.Symbolic.TypedCode: op'div :: (Fractional a) => Code (a -> a -> a)
+ Data.Symbolic.TypedCode: op'mul :: (Num a) => Code (a -> a -> a)
+ Data.Symbolic.TypedCode: op'negate :: (Num a) => Code (a -> a)
+ Data.Symbolic.TypedCode: op'pi :: (Floating a) => Code a
+ Data.Symbolic.TypedCode: op'recip :: (Fractional a) => Code (a -> a)
+ Data.Symbolic.TypedCode: op'sin :: (Floating a) => Code (a -> a)
+ Data.Symbolic.TypedCode: op'sub :: (Num a) => Code (a -> a -> a)
+ Data.Symbolic.TypedCode: rationalC :: (Fractional a) => Rational -> Code a
+ Data.Symbolic.TypedCode: reflectDF :: Var a -> Code a -> QCode (a -> a)
+ Data.Symbolic.TypedCode: reflectQC :: Q (Code a) -> Q Exp
+ Data.Symbolic.TypedCode: showQC :: Q (Code a) -> IO ()
+ Data.Symbolic.TypedCode: type QCode a = Q (Code a)
+ Data.Symbolic.TypedCode: var'exp :: Var a -> Code a
+ Data.Symbolic.TypedCodeAux: reifyName :: Q Exp -> Q Exp

Files

Control/CCCxe.hs view
@@ -183,7 +183,7 @@   P2 (Either (CCT (P2 w1 w2) m x w1) (CCT (P2 w1 w2) m x w2))  --- | There are two generalized prompts of the flavor P2"+-- | There are two generalized prompts of the flavor P2 p2L :: Prompt (P2 w1 w2) m w1 p2L = (inj, prj)  where
Control/CCExc.hs view
@@ -190,7 +190,7 @@   P2 (Either (CCT (P2 w1 w2) m x w1) (CCT (P2 w1 w2) m x w2))  --- | There are two generalized prompts of the flavor P2:+-- | There are two generalized prompts of the flavor P2 p2L :: Prompt (P2 w1 w2) m w1 p2L = (inj, prj)  where
Control/CaughtMonadIO.hs view
@@ -31,8 +31,8 @@ import Data.Typeable import Data.Dynamic import Control.Monad.Trans-import Control.Exception hiding (catch, catchDyn)-import qualified Control.Exception (catch)+import Control.OldException hiding (catch, catchDyn)+import qualified Control.OldException (catch) import Control.Monad.Reader import Control.Monad.Writer import Control.Monad.State@@ -81,7 +81,7 @@      gcatch :: m a -> (Exception -> m a) -> m a  instance CaughtMonadIO IO where-     gcatch = Control.Exception.catch+     gcatch = Control.OldException.catch  instance (CaughtMonadIO m, Error e) => CaughtMonadIO (ErrorT e m) where      gcatch m f = mapErrorT (\m -> gcatch m (\e -> runErrorT $ f e)) m
+ Data/Symbolic/Diff.hs view
@@ -0,0 +1,295 @@+{-# OPTIONS -fglasgow-exts #-}+{-# LANGUAGE TemplateHaskell #-}++-- | Reify the (compiled) code to its typed TH representation +-- (or, the dictionary *view*, to be precise) and reflect\/compile that code.+-- We must spread the code through several modules, due to the+-- particular requirement of the Template Haskell.+-- See DiffTest.hs for reflection of the differentiated TH code back+-- into (machine) code.++module Data.Symbolic.Diff where++import Data.Symbolic.TypedCode+++-- | Lift Nums, Fractionals, and Floating to code expressions+--+instance Num a => Num (Code a) where+    x + y = op'add `appC` x `appC` y+    x - y = op'sub `appC` x `appC` y+    x * y = op'mul `appC` x `appC` y+    negate x = op'negate `appC` x+    fromInteger = integerC++instance Fractional a => Fractional (Code a) where+    x / y = op'div `appC` x `appC` y+    recip x = op'recip `appC` x+    fromRational = rationalC++instance Floating a => Floating (Code a) where+    pi = op'pi+    sin x = op'sin `appC` x+    cos x = op'cos `appC` x++testf1 :: Num a => a+testf1 = 1 + 2+testf1' = return (testf1 :: Code Int)+testf1'' = showQC testf1' -- (GHC.Num.+) 1 2+++-- | We can define a function+--+test1f x = let y = x * x in y + 1+test1 = test1f (2.0::Float)++-- | we can even compile it. At any point, we can reify it, into+-- a `dictionary view'+-- The result is the TH code, which we can print, and compile back+-- to the code. We can also differentiate the TH code, simplify it,+-- partially evaluate it, etc.+--+test1c = new'diffVar >>= \ (v::Var Float) -> return $ (test1f (var'exp v),v)+test1r = test1c >>= \ (c,v) -> reflectDF v c+test1cp = showQC test1r++-- and reflect it back, see DiffTest.hs+{-+We must stress that there is no `reify' function. One may say it is+built into Haskell already.+++    *Diff> test1+    5.0+    *DiffTest> test1'+    5.0+    *Diff> test1cp+    \dx_0 -> GHC.Num.+ (GHC.Num.* dx_0 dx_0) 1+-}+++-- | Symbolic Differentiation of the reified, typed TH code expressions+-- The derivative over the code is a type preserving operation+--+diffC :: (Floating a, Floating b) => Var b -> Code a -> Code a++diffC v c | Just _  <- on'litC c = 0+diffC v c | Just ev <- on'varC v c = either (const 1) (const 0) ev++diffC v c | Just (x,y) <- on'2opC op'add c =+			  (diffC v x) + (diffC v y)++diffC v c | Just (x,y) <- on'2opC op'sub c =+			  (diffC v x) - (diffC v y)++diffC v c | Just (x,y) <- on'2opC op'mul c =+			    ((diffC v x) * y) + (x * (diffC v y))++diffC v c | Just (x,y) <- on'2opC op'div c =+			  ((diffC v x) * y - x * (diffC v y)) / (y*y)++diffC v c | Just x <- on'1opC op'negate c =+			  negate (diffC v x)++diffC v c | Just x <- on'1opC op'recip c =+			  negate (diffC v x) / (x*x)++diffC v c | Just x <- on'1opC op'sin c =+			  (diffC v x) * cos x++diffC v c | Just x <- on'1opC op'cos c =+			  negate ((diffC v x) * sin x)++diffC v c = error $ "Cannot handle code: " ++ show c+++test1d = test1c >>= \ (c,v) -> reflectDF v $ diffC v c+test1dp = showQC test1d++{-+ *Diff> test1dp+ \dx_0 -> (GHC.Num.+) ((GHC.Num.+) ((GHC.Num.*) 1 dx_0) ((GHC.Num.*) dx_0 1)) 0+-}+++-- | Simplification rules+-- simplification is type-preserving+-- obviously, simplification is an `open-ended' problem:+-- we could even recognize common sub-expressions and simplify them+-- by introducing let binding.+-- In the following however, we do trivial simplification only.+-- One can always add more simplification rules later.+--+simpleC :: Floating a => Var b -> Code a -> Code a++-- | repeat until no simplifications are made+simpleC v c | Just c' <- simpleCL v c = simpleC v c'+simpleC v c = c++simpleCL :: Floating a => Var b -> Code a -> Maybe (Code a)++simpleCL v c | Just _ <- on'litC c = Nothing+simpleCL v c | Just _ <- on'varC v c = Nothing++simpleCL v c | Just (x,y) <- on'2opC op'add c =+			     simple'recur op'add sadd v x y+  where+  sadd x y | Just 0 <- on'litRationalC x = Just y+  sadd x y | Just 0 <- on'litRationalC y = Just x+		       -- constant folding+  sadd x y | (Just x, Just y) <- (on'litRationalC x, on'litRationalC y)+			      = Just (fromRational $ x + y)+  sadd x y = Nothing++simpleCL v c | Just (x,y) <- on'2opC op'sub c =+			     simple'recur op'sub ssub v x y+  where+  ssub x y | Just 0 <- on'litRationalC y = Just x+		       -- constant folding+  ssub x y | (Just x, Just y) <- (on'litRationalC x, on'litRationalC y)+			      = Just (fromRational $ x - y)+  ssub x y = Nothing+++simpleCL v c | Just (x,y) <- on'2opC op'mul c =+			     simple'recur op'mul smul v x y+  where+  smul x y | Just 0 <- on'litRationalC x = Just (fromRational 0)+  smul x y | Just 0 <- on'litRationalC y = Just (fromRational 0)+  smul x y | Just 1 <- on'litRationalC x = Just y+  smul x y | Just 1 <- on'litRationalC y = Just x+  smul x y | (Just x, Just y) <- (on'litRationalC x, on'litRationalC y)+			      = Just (fromRational $ x * y)+  smul x y = Nothing -- error $ unwords ["here",show x,show y] -- Nothing+++simpleCL v c | Just (x,y) <- on'2opC op'div c =+			     simple'recur op'div sdiv v x y+  where+  sdiv x y | Just 0 <- on'litRationalC x = Just (fromRational 0)+  sdiv x y = Nothing -- error $ unwords ["here",show x,show y] -- Nothing++simpleCL v c | Just x <- on'1opC op'negate c =+			     simple'recur1 op'negate sneg v x+  where+  sneg x | Just 0 <- on'litRationalC x = Just (fromRational 0)+  sneg x = Nothing +++simpleCL v c = Nothing++simple'recur op fn v x y = +    case (simpleCL v x, simpleCL v y) of+	     (Nothing,Nothing) -> fn x y+	     (Just x,Nothing)  -> Just (op `appC` x `appC` y)+	     (Nothing,Just y)  -> Just (op `appC` x `appC` y)+	     (Just x,Just y)   -> Just (op `appC` x `appC` y)++simple'recur1 op fn v x = +    case simpleCL v x of+	     Nothing -> fn x+	     Just x  -> Just (op `appC` x)++test1ds = test1c >>= \ (c,v) -> reflectDF v $ simpleC v $ diffC v c+test1dsp = showQC test1ds++{-+   *Diff> test1dsp+   \dx_0 -> GHC.Num.+ dx_0 dx_0+-}++-- | And that's about it. Putting it all together gives us:+--+diff_fn :: Floating b => (forall a. Floating a => a -> a) -> QCode (b -> b)+diff_fn f = +    do+    v <- new'diffVar+    let body = f (var'exp v)   -- reified body of the function+    reflectDF v . simpleC v . diffC v $ body -- differentiate and simplify++-- | This is a useful helper to show us the code of the function in question+show_fn :: (forall a. Floating a => a -> a) -> IO ()+show_fn f = showQC (+		    do+		    v <- new'diffVar+		    reflectDF v (f (var'exp v)))++-- We can either print the result of diff_fn, or compile it+-- (that is, splice it: see DiffTest.hs)+++-- | More examples+--+test2f x = foldl (\z c -> x*z + c) 0 [1,2,3]+test2n = test2f (4::Float)  -- 27.0+test2s = show_fn test2f++{-+  *Diff> test2s+  \dx_0 -> GHC.Num.+ (GHC.Num.* dx_0 (GHC.Num.+ +     (GHC.Num.* dx_0 (GHC.Num.+ (GHC.Num.* dx_0 0) 1)) 2)) 3+-}++test2ds = showQC (diff_fn test2f)++{- Not too bad: 2*x + 2+ *Diff> test2ds+ \dx_0 -> GHC.Num.+ (GHC.Num.+ dx_0 2) dx_0+-}++{- The differentiated code can be `compiled back', see DiffTest.hs+  test2dn = $(reflectQC (diff_fn test2f)) (4::Float)+  -- 10.0+-}++-- Check the constant folding+test11f x = 2*x + 3*x+test11ds = showQC (diff_fn test11f) -- \dx_0 -> 5%1+++-- | Here's a slightly more complex example:+--+test5f x = sin (5*x + pi/2) + cos(1 / x)+test5n = test5f (pi::Float) -- cos(1/pi)-1 == -5.023426e-2+test5ds = showQC (diff_fn test5f)+++{- which isn't too bad: quite optimal, actually+*Diff> test5ds+\dx_0 -> GHC.Num.+ (GHC.Num.* 5 (GHC.Float.cos +    (GHC.Num.+ (GHC.Num.* 5 dx_0) (GHC.Real./ GHC.Float.pi 2))))+   (GHC.Num.negate (GHC.Num.* (GHC.Real./ ((-1)%1) (GHC.Num.* dx_0 dx_0)) +        (GHC.Float.sin (GHC.Real./ 1 dx_0))))+-}++-- One may evaluate the function test5f numerically, differentiate it+-- symbolically, check the result of differentiation -- and evaluate it+-- numerically right away. See test5dn in DiffTest.hs for the latter.+++-- | We can even do partial derivatives:+--+test3f x y = (x*y + (5*x*x)) / y++test4x y = diff_fn (\x -> test3f x (fromIntegral y))+test4y x = diff_fn (test3f (fromInteger x))++test4xds = showQC (test4x 1) -- 1 + 10*x+test4yds = showQC (test4y 5) ++{-+ *DiffTest> test4yds+ \dx_0 -> GHC.Real./ (GHC.Num.- (GHC.Num.* 5 dx_0) +             (GHC.Num.+ (GHC.Num.* 5 dx_0) (125%1))) (GHC.Num.* dx_0 dx_0)++-}++{- In DiffTest.hs+-- partial derivative with respect to x+test4xdn = $(reflectQC (test4x 1)) (2::Float)+-- 21.0++-- | partial derivative with respect to y+test4ydn = $(reflectQC (test4y 5)) (5::Float)+-- -5.0+-}
+ Data/Symbolic/DiffTest.hs view
@@ -0,0 +1,33 @@+{-# OPTIONS -fglasgow-exts #-}+{-# LANGUAGE TemplateHaskell #-} ++-- | Running the splicing tests from Diff.hs.+-- Due to the TH requirement, this code must be in a separate module.+--+module Data.Symbolic.DiffTest where++import Data.Symbolic.Diff+import Data.Symbolic.TypedCode++testrf1 = $(reflectQC testf1')++test1' = $(reflectQC test1r) 2.0+test1ds' = $(reflectQC test1ds) 2.0++test2dn = $(reflectQC (diff_fn test2f)) (4::Float)+-- 10.0++test11dn = $(reflectQC (diff_fn test11f)) (4::Float)+-- 5.0++test5dn = $(reflectQC (diff_fn test5f)) (pi::Float)+-- 3.171623e-2, approx sin(1/pi)/pi/pi+-- approx, because: cos(5*(pi::Float) + pi/2) isn't exactly 0++-- | partial derivative with respect to x+test4xdn = $(reflectQC (test4x 1)) (2::Float)+-- 21.0++-- | partial derivative with respect to y+test4ydn = $(reflectQC (test4y 5)) (5::Float)+-- -5.0
+ Data/Symbolic/TypedCode.hs view
@@ -0,0 +1,154 @@+{-# OPTIONS -fglasgow-exts #-}+{-# LANGUAGE TemplateHaskell #-}++-- | Template Haskell code is untyped, which is a bummer and leads to late+-- error reporting. We make code expressions typed, at least for our particular+-- domain.+--+module Data.Symbolic.TypedCode (+                  Code, -- only the type is exported,+                        -- data constructor is private+                  Var,  -- ditto+                  QCode,+                  reflectQC, showQC,++                  -- typed primitive operations+                  op'add, op'sub, op'mul, op'div, op'negate, op'recip,+                  op'sin, op'cos, op'pi,++                  -- Code combinators+                  appC,++                  -- Lifting from primitive datatypes to Code+                  integerC, rationalC,++                  -- create a variable to differentiate over+                  new'diffVar, var'exp, reflectDF,++                  -- combinators for the intensional code analysis+                  on'varC, on'litC, on'litRationalC, on'1opC, on'2opC+                 ) where++import Data.Symbolic.TypedCodeAux+import Language.Haskell.TH+import Language.Haskell.TH.Ppr++-- | The data type of a typed TH code experssion. The phantom parameter 'a'+-- is the type.+--+newtype Code a = Code {unC :: Exp} deriving (Eq, Show)+type QCode a = Q (Code a)+newtype Var a = Var Name++show_code cde = runQ cde >>= putStrLn . pprint++showQC :: Q (Code a) -> IO ()+showQC qc = runQ qc >>= putStrLn . pprint . unC++-- | This function is useful when splicing code expressions+-- See DiffTest.hs for the examples of its use.+reflectQC :: Q (Code a) -> Q Exp+reflectQC qc = qc >>= return . unC+++-- | Typed primitive operations+--+op'add :: Num a => Code (a->a->a)+op'add = Code . VarE $ $(reifyName [e| (+) |])+op'sub :: Num a => Code (a->a->a)+op'sub = Code . VarE $ $(reifyName [e| (-) |])+op'mul :: Num a => Code (a->a->a)+op'mul = Code . VarE $ $(reifyName [e| (*) |])+op'div :: Fractional a => Code (a->a->a)+op'div = Code . VarE $ $(reifyName [e| (/) |])+op'negate :: Num a => Code (a->a)+op'negate = Code . VarE $ $(reifyName [e| negate |])+op'recip :: Fractional a => Code (a->a)+op'recip = Code . VarE $ $(reifyName [e| recip |])++op'sin :: Floating a => Code (a->a)+op'sin = Code . VarE $ $(reifyName [e| sin |])+op'cos :: Floating a => Code (a->a)+op'cos = Code . VarE $ $(reifyName [e| cos |])+op'pi :: Floating a => Code a+op'pi = Code . VarE $ $(reifyName [e| pi |])++-- | Code expression combinators +--+appC :: Code (a->b) -> Code a -> Code b+appC (Code f) (Code x) = Code $ AppE f x++-- | Lifting from primitive datatypes to Code+--+integerC :: Num a => Integer -> Code a +integerC x = Code . LitE . integerL $ x+rationalC :: Fractional a => Rational -> Code a +rationalC x = Code . LitE . rationalL $ x++-- | A distinguished variable (over which we differentiate)+new'diffVar :: Q (Var a)+new'diffVar = newName "dx" >>= return . Var++-- | Lift this variable to Code+var'exp :: Var a -> Code a+var'exp (Var name) = Code . VarE $ name++-- abstract over the differentiation variable+-- That is, convert from+--+-- > diffVar |- body +--+-- to+--+-- > |- diffVar -> body+--+-- In this formulation, this looks exactly like the Deduction theorem!+-- We take advantage of the fact that TH is non-hygienic.+-- That is, instead of binding a fresh variable and traversing+-- the body replacing diffVar with that variable (as we should do+-- in MetaOCaml), we simply non-hygienically bind the diffVar.+-- We save ourselves the term traversal: normalization by evaluation.+--+reflectDF:: Var a -> Code a -> QCode (a->a)+reflectDF (Var name) (Code body) = +    lam1E (varP name) (return body) >>= return . Code++e1 = [e| 1 + 2 |]+t1 = show_code e1+t2 (InfixE me1 (VarE name) me3) = reify name+t2' = show_code (e1 >>= t2)+++-- | Intensional code analysis+-- Alas, TH.Exp is not a GADT. So, we have to do their emulation...+--+on'litC :: Code a -> Maybe (Code a)+on'litC c@(Code (LitE _)) = Just c+on'litC _ = Nothing++on'litRationalC :: Code a -> Maybe Rational+on'litRationalC (Code (LitE lit)) = +    case lit of+         IntegerL x    -> Just $ toRational x+         IntPrimL x    -> Just $ toRational x+         RationalL x   -> Just x+         FloatPrimL x  -> Just x+         DoublePrimL x -> Just x+         _ -> Nothing+on'litRationalC _ = Nothing+++on'varC :: Var a -> Code b -> Maybe (Either (Var a) (Var b))+on'varC v@(Var name) (Code c) | c == VarE name = Just (Left v)+on'varC _ (Code (VarE n)) = Just . Right . Var $ n+on'varC _ _ = Nothing++on'2opC :: Code (a->b->c) -> Code d -> Maybe (Code a, Code b)+on'2opC (Code op) (Code (AppE (AppE f x) y)) | op == f+    = Just (Code x,Code y)+on'2opC _ _ = Nothing++on'1opC :: Code (a->b) -> Code d -> Maybe (Code a)+on'1opC (Code op) (Code (AppE f x)) | op == f+    = Just (Code x)+on'1opC _ _ = Nothing
+ Data/Symbolic/TypedCodeAux.hs view
@@ -0,0 +1,50 @@+{-# OPTIONS -fglasgow-exts #-}+{-# LANGUAGE TemplateHaskell #-}++-- | Obtain the Name that corresponds to a top-level (Prelude-level)+-- Haskell identifier.+-- Given an expression such as [e| (+) |] we return the expression+-- that is the application of mkNameG_v to the correct strings.+-- That expression, when spliced in, will compute exactly the same+-- name that corresponds to the one we started with, that is, (+).+-- Note that (+) was the identifier, not the name.+-- The result of splicing reifyName can be used in splices+-- (see the Diff.hs for examples).+-- We essentially apply the TH to itself and emulate more than one stage+-- of computation.+--+module Data.Symbolic.TypedCodeAux where++import Language.Haskell.TH+import Language.Haskell.TH.Syntax+import Language.Haskell.TH.Ppr++reifyName :: Q Exp -> Q Exp++{- For GHC prior to 6.6, use the following code. TH has changed in+   GHC 6.6+reifyName nameE = nameE >>= +		    \ (VarE (Name occname (NameG VarName mn))) -> +			[e| mkNameG_v $(litE . stringL . modString $ mn)+			 $(litE . stringL . occString $ occname)|]++-}++reifyName nameE = nameE >>= +		    \ (VarE (Name occname (NameG VarName pn mn))) -> +			[e| mkNameG_v+			 $(litE . stringL . pkgString $ pn)+			 $(litE . stringL . modString $ mn)+			 $(litE . stringL . occString $ occname)|]++++{-+  Remnants of early experiments++foo = $([e| (+) |] >>= \ (VarE name) -> global name)+-- foo1 = $([e| (+) |] >>= \ (VarE name) -> global $ mkName "GHC.Num.+")+foo1 = $([e| (+) |] >>= \ (VarE (Name occname (NameG VarName mn))) -> +	 [e| mkNameG_v $(litE . stringL . modString $ mn)+	               $(litE . stringL . occString $ occname)|])+-}
Language/TEval/TInfTM.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE PatternGuards #-} -- | Simply-typed Curry-style (nominal) lambda-calculus -- with integers and zero-comparison -- Type inference. Hiding the single-threaded state via simple
System/SafeHandles.hs view
@@ -67,7 +67,7 @@      ) where  import System.IO-import Control.Exception+import Control.OldException import Control.Monad.Reader import Control.Monad.Trans import Data.IORef
liboleg.cabal view
@@ -1,5 +1,5 @@ name:           liboleg-version:        2010.1.9.0+version:        2010.1.10.0 license:        BSD3 license-file:   LICENSE author:         Oleg Kiselyov@@ -18,7 +18,7 @@  library     build-depends:-            base >= 2 && < 4,+            base >=4 && <5,             containers,             mtl,             unix,@@ -30,6 +30,11 @@             Data.Class1             Data.Class2             Data.Numerals++            Data.Symbolic.Diff+            Data.Symbolic.DiffTest+            Data.Symbolic.TypedCodeAux+            Data.Symbolic.TypedCode              Control.CaughtMonadIO             Control.ShiftResetGenuine