packages feed

Adaptive 0.1 → 0.22

raw patch · 14 files changed

+827/−506 lines, 14 filesdep +haskell98dep ~basesetup-changednew-component:exe:spreadsheetnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependencies added: haskell98

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.Adaptive: Adaptive :: [a] -> Adaptive a
- Data.Adaptive: approx :: (RealFloat a, Ord a) => Adaptive a -> a
- Data.Adaptive: approx' :: (Real a, RealFloat b) => Adaptive a -> b
- Data.Adaptive: approxFast :: Num a => Adaptive a -> a
- Data.Adaptive: epsilon :: RealFloat a => a
- Data.Adaptive: fromFloatingPoint :: RealFloat a => a -> Adaptive a
- Data.Adaptive: instance (Num a, RealFloat a) => Eq (Adaptive a)
- Data.Adaptive: instance (Num a, RealFloat a) => Num (Adaptive a)
- Data.Adaptive: instance (Num a, RealFloat a) => Ord (Adaptive a)
- Data.Adaptive: instance (RealFloat a, Floating a) => Floating (Adaptive a)
- Data.Adaptive: instance (RealFloat a, Fractional a) => Fractional (Adaptive a)
- Data.Adaptive: instance (RealFloat a, Real a) => Real (Adaptive a)
- Data.Adaptive: instance (RealFloat a, RealFrac a) => RealFrac (Adaptive a)
- Data.Adaptive: instance (Show a, RealFloat a) => Show (Adaptive a)
- Data.Adaptive: instance RealFloat a => RealFloat (Adaptive a)
- Data.Adaptive: newtype Adaptive a
- Data.Adaptive: splitter :: RealFloat a => a
+ Control.Monad.Adaptive: change :: Ref m r => Modifiable m r a -> a -> Adaptive m r ()
+ Control.Monad.Adaptive: class InM m'
+ Control.Monad.Adaptive: class (Monad (n m r), Ref m r) => NewMod n m r
+ Control.Monad.Adaptive: data Adaptive m r a
+ Control.Monad.Adaptive: data Changeable m r a
+ Control.Monad.Adaptive: data Modifiable m r a
+ Control.Monad.Adaptive: inCh :: Ref m r => Changeable m r a -> Adaptive m r a
+ Control.Monad.Adaptive: inM :: (InM m', Ref m r) => m a -> m' m r a
+ Control.Monad.Adaptive: instance EqRef r => Eq (Modifiable m r a)
+ Control.Monad.Adaptive: instance InM Adaptive
+ Control.Monad.Adaptive: instance InM Changeable
+ Control.Monad.Adaptive: instance InOL Adaptive
+ Control.Monad.Adaptive: instance InOL Changeable
+ Control.Monad.Adaptive: instance Ref m r => Functor (Adaptive m r)
+ Control.Monad.Adaptive: instance Ref m r => Functor (Changeable m r)
+ Control.Monad.Adaptive: instance Ref m r => Monad (Adaptive m r)
+ Control.Monad.Adaptive: instance Ref m r => Monad (Changeable m r)
+ Control.Monad.Adaptive: instance Ref m r => NewMod Adaptive m r
+ Control.Monad.Adaptive: instance Ref m r => NewMod Changeable m r
+ Control.Monad.Adaptive: instance Ref m r => Ref (Adaptive m r) r
+ Control.Monad.Adaptive: instance Ref m r => Ref (Changeable m r) r
+ Control.Monad.Adaptive: newMod :: (Eq a, NewMod n m r) => Changeable m r a -> n m r (Modifiable m r a)
+ Control.Monad.Adaptive: newModBy :: NewMod n m r => (a -> a -> Bool) -> Changeable m r a -> n m r (Modifiable m r a)
+ Control.Monad.Adaptive: propagate :: Ref m r => Adaptive m r ()
+ Control.Monad.Adaptive: readMod :: Ref m r => Modifiable m r a -> Changeable m r a
+ Control.Monad.Adaptive: run :: Ref m r => Adaptive m r a -> m a
+ Control.Monad.Adaptive.CircularList: circularList :: Ref m r => a -> m (CircularList m r a)
+ Control.Monad.Adaptive.CircularList: data CircularList m r a
+ Control.Monad.Adaptive.CircularList: delete :: Ref m r => CircularList m r a -> m ()
+ Control.Monad.Adaptive.CircularList: insert :: Ref m r => CircularList m r a -> a -> m (CircularList m r a)
+ Control.Monad.Adaptive.CircularList: next :: Ref m r => CircularList m r a -> m (CircularList m r a)
+ Control.Monad.Adaptive.CircularList: previous :: Ref m r => CircularList m r a -> m (CircularList m r a)
+ Control.Monad.Adaptive.CircularList: update :: Ref m r => CircularList m r a -> a -> m ()
+ Control.Monad.Adaptive.CircularList: val :: Ref m r => CircularList m r a -> m a
+ Control.Monad.Adaptive.MonadUtil: ifM :: Monad m => m Bool -> m a -> m a -> m a
+ Control.Monad.Adaptive.MonadUtil: unlessM :: Monad m => m Bool -> m () -> m ()
+ Control.Monad.Adaptive.MonadUtil: whenM :: Monad m => m Bool -> m () -> m ()
+ Control.Monad.Adaptive.OrderedList: base :: Ref m r => OrderedList m r a (Record m r a)
+ Control.Monad.Adaptive.OrderedList: data OrderedList m r a b
+ Control.Monad.Adaptive.OrderedList: data Record m r a
+ Control.Monad.Adaptive.OrderedList: delete :: Ref m r => Record m r a -> OrderedList m r a ()
+ Control.Monad.Adaptive.OrderedList: deleted :: Ref m r => Record m r a -> OrderedList m r a Bool
+ Control.Monad.Adaptive.OrderedList: inM :: Ref m r => m b -> OrderedList m r a b
+ Control.Monad.Adaptive.OrderedList: insert :: Ref m r => Record m r a -> a -> OrderedList m r a (Record m r a)
+ Control.Monad.Adaptive.OrderedList: instance (Ref m r, Integral b) => Integral (OrderedList m r a b)
+ Control.Monad.Adaptive.OrderedList: instance (Ref m r, Num b) => Num (OrderedList m r a b)
+ Control.Monad.Adaptive.OrderedList: instance (Ref m r, Real b) => Real (OrderedList m r a b)
+ Control.Monad.Adaptive.OrderedList: instance Enum (OrderedList m r a b)
+ Control.Monad.Adaptive.OrderedList: instance Eq (OrderedList m r a b)
+ Control.Monad.Adaptive.OrderedList: instance Ord (OrderedList m r a b)
+ Control.Monad.Adaptive.OrderedList: instance Ref m r => Functor (OrderedList m r a)
+ Control.Monad.Adaptive.OrderedList: instance Ref m r => Monad (OrderedList m r a)
+ Control.Monad.Adaptive.OrderedList: instance Ref m r => Ref (OrderedList m r a) r
+ Control.Monad.Adaptive.OrderedList: instance Show (OrderedList m r a b)
+ Control.Monad.Adaptive.OrderedList: next :: Ref m r => Record m r a -> OrderedList m r a (Record m r a)
+ Control.Monad.Adaptive.OrderedList: order :: Ref m r => Record m r a -> Record m r a -> OrderedList m r a Ordering
+ Control.Monad.Adaptive.OrderedList: record :: Ref m r => Record m r a -> OrderedList m r a (Bool, Integer, a)
+ Control.Monad.Adaptive.OrderedList: run :: Ref m r => OrderedList m r a b -> m b
+ Control.Monad.Adaptive.OrderedList: rval :: Ref m r => Record m r a -> OrderedList m r a a
+ Control.Monad.Adaptive.OrderedList: spliceOut :: Ref m r => Record m r a -> Record m r a -> OrderedList m r a ()
+ Control.Monad.Adaptive.PriorityQueue: data PriorityQueue a
+ Control.Monad.Adaptive.PriorityQueue: empty :: PriorityQueue a
+ Control.Monad.Adaptive.PriorityQueue: insert :: Ord a => a -> PriorityQueue a -> PriorityQueue a
+ Control.Monad.Adaptive.PriorityQueue: insertM :: Monad m => (a -> a -> m Ordering) -> a -> PriorityQueue a -> m (PriorityQueue a)
+ Control.Monad.Adaptive.PriorityQueue: min :: PriorityQueue a -> Maybe (a, PriorityQueue a)
+ Control.Monad.Adaptive.Ref: class EqRef r
+ Control.Monad.Adaptive.Ref: class (EqRef r, Functor m, Monad m) => Ref m r | m -> r
+ Control.Monad.Adaptive.Ref: eqRef :: EqRef r => r a -> r a -> Bool
+ Control.Monad.Adaptive.Ref: instance EqRef (STRef s)
+ Control.Monad.Adaptive.Ref: instance EqRef IORef
+ Control.Monad.Adaptive.Ref: instance Ref (ST s) (STRef s)
+ Control.Monad.Adaptive.Ref: instance Ref IO IORef
+ Control.Monad.Adaptive.Ref: mapRef :: Ref m r => (a -> a) -> r a -> m ()
+ Control.Monad.Adaptive.Ref: newRef :: Ref m r => a -> m (r a)
+ Control.Monad.Adaptive.Ref: readRef :: Ref m r => r a -> m a
+ Control.Monad.Adaptive.Ref: writeRef :: Ref m r => r a -> a -> m ()

Files

Adaptive.cabal view
@@ -1,61 +1,20 @@--- Adaptive.cabal auto-generated by cabal init. For additional--- options, see--- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.--- The name of the package. Name:                Adaptive---- The package version. See the Haskell package versioning policy--- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for--- standards guiding when and how versions should be incremented.-Version:             0.1---- A short (one-line) description of the package.-Synopsis:            Adaptive precision floating-point arithmetic---- A longer description of the package.-Description:         Lazy arithmetic computed with as much precision as demanded ---- URL for the project homepage or repository.-Homepage:            http://github.com/HackerFoo/Adaptive---- The license under which the package is released.-License:             LGPL-3---- The file containing the license text.+Version:             0.22+Synopsis:            Library for incremental computing.+Description:         This is a Haskell (plus some extensions) implementation +		     of a library for incremental computing.  It closely +		     follows the implementation in the nice POPL 2002 paper +		     "Adaptive Functional Programming", by Umut Acar, +		     Guy Blelloch and Bob Harper.+License:             BSD3 License-file:        LICENSE---- The package author(s).-Author:              Dustin DeWeese---- An email address to which users can send suggestions, bug reports,--- and patches.-Maintainer:          dustin.deweese@gmail.com---- A copyright notice.--- Copyright:           --Category:            Data--Build-type:          Simple---- Extra files to be distributed with the package, such as examples or--- a README.--- Extra-source-files:  ---- Constraint on the version of Cabal needed to build this package.-Cabal-version:       >=1.4+Author:              Magnus Carlsson+Maintainer:          Magnus Carlsson <magnus@galois.com>+Build-Depends:       base, haskell98+Exposed-modules:     Control.Monad.Adaptive, Control.Monad.Adaptive.Ref,Control.Monad.Adaptive.PriorityQueue, Control.Monad.Adaptive.OrderedList, Control.Monad.Adaptive.CircularList, Control.Monad.Adaptive.MonadUtil+data-files:	     ChangeLog, README+build-type:	     Simple +Executable:          spreadsheet+Main-is:             spreadsheet.hs -Library-  -- Modules exported by the library.-  Exposed-modules:     Data.Adaptive-  -  -- Packages needed in order to build this package.-  Build-depends:       base >= 4 && < 5-  -  -- Modules not exported by this package.-  -- Other-modules:       -  -  -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.-  -- Build-tools:         -  
+ ChangeLog view
@@ -0,0 +1,12 @@+2008-07-14    <pj@csee.ltu.se>++	* Version 0.22, adapted for Hugs 20060908 and ghc 6.8.2.++2005-07-09    <magnus@cse.ogi.edu>++	* Version 0.21, adapted for Hugs 20050308 and ghc 6.4, by+	Andrew Pimlott <andrew@pimlott.net>.++2002-03-18    <magnus@cse.ogi.edu>++	* Version 0.2, public release.
+ Control/Monad/Adaptive.hs view
@@ -0,0 +1,212 @@+-- -*- haskell-hugs-program-args: ("+." "-98") -*-+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}++-- An monadic variant of the library from "Adaptive Functional+-- Programming", by Acar, Blelloch and Harper (POPL 2002).++-- Magnus Carlsson, magnus@cse.ogi.edu++module Control.Monad.Adaptive+  ( Adaptive+  , Changeable+  , Modifiable+  , readMod+  , InM(..)+  , change+  , propagate+  , run+  , inCh+  , NewMod(..)+  , newMod++ ) where++import Prelude +import Monad(ap,unless)+import Control.Monad.Adaptive.MonadUtil+import Control.Monad.Adaptive.Ref+import qualified Control.Monad.Adaptive.OrderedList as OL+import Control.Monad.Adaptive.OrderedList(OrderedList)+import qualified Control.Monad.Adaptive.PriorityQueue as PQ+import Control.Monad.Adaptive.PriorityQueue(PriorityQueue)++-- Export:+class InM m' where+   inM :: Ref m r => m a -> m' m r a++class (Monad (n m r), Ref m r) => NewMod n m r where+   newModBy :: (a -> a -> Bool) -> Changeable m r a -> n m r (Modifiable m r a)+++newMod    :: (Eq a, NewMod n m r) => +             Changeable m r a -> n m r (Modifiable m r a)+change    :: Ref m r => Modifiable m r a -> a -> Adaptive m r ()+propagate :: Ref m r => Adaptive m r ()+readMod   :: Ref m r => Modifiable m r a -> Changeable m r a+run       :: Ref m r => Adaptive m r a -> m a+inCh      :: Ref m r => Changeable m r a -> Adaptive m r a++-- Local:++type ReComp m r = (Adaptive m r (), TimeStamp m r, TimeStamp m r)+startTime (_,s,_) = s++type TimeStamp m r = OL.Record m r ()++newtype Adaptive m r a = +  Ad ((r (PriorityQueue (ReComp m r)), r (TimeStamp m r)) -> +      OrderedList m r () a)++newtype Changeable m r a = Ch (K (Adaptive m r ()) a)+type K b a = (a -> b) -> b++newtype Modifiable m r a = Mo (r a, r (a -> Adaptive m r ()), r [ReComp m r])++cont :: Ref m r => +        ((a -> Adaptive m r ()) -> Adaptive m r ()) -> Changeable m r a+cont m = Ch m++deCh (Ch m) = m+deAd (Ad m) = m++inAd :: Ref m r => Adaptive m r a -> Changeable m r a+inAd m = Ch $ (m >>=)++class InOL m' where+  inOL :: Ref m r => OrderedList m r () b -> m' m r b++instance InOL Adaptive where+  inOL m = Ad $ const m++instance InOL Changeable where+  inOL m = inAd (inOL m)++instance Ref m r => Ref (Changeable m r) r where+  newRef v     = inM $ newRef v+  readRef x    = inM $ readRef x+  writeRef x v = inM $ writeRef x v++instance Ref m r => Monad (Changeable m r) where+  return a   = Ch $ \k -> k a+  Ch m >>= f = Ch $ \k -> m $ \a -> deCh (f a) k++instance Ref m r => Functor (Changeable m r) where+  fmap f m = m >>= return . f++instance Ref m r => Ref (Adaptive m r) r where+  newRef v     = inM $ newRef v+  readRef x    = inM $ readRef x+  writeRef x v = inM $ writeRef x v++instance Ref m r => Monad (Adaptive m r) where+  return a   = Ad $ \e -> return a+  Ad m >>= f = Ad $ \e -> m e >>= \a -> deAd (f a) e++instance Ref m r => Functor (Adaptive m r) where+  fmap f m = m >>= return . f++readMod (Mo (r,chg,es)) = do+   start <- inAd stepTime+   cont $ \k -> do+     let reader = do readRef r >>= k+                     now <- readCurrentTime+                     mapRef ((reader,start,now):) es+     reader++pqRef :: Ref m r => Adaptive m r (r (PriorityQueue (ReComp m r)))+pqRef = Ad $ \ (pq,ct) -> return pq++readPq :: Ref m r => Adaptive m r (PriorityQueue (ReComp m r))+readPq = pqRef >>= readRef+writePq a = pqRef >>= flip writeRef a++ctRef :: Ref m r => Adaptive m r (r (TimeStamp m r))+ctRef = Ad $ \ (pq,ct) -> return ct+readCurrentTime :: Ref m r => Adaptive m r (TimeStamp m r)+readCurrentTime = ctRef >>= readRef+writeCurrentTime a = ctRef >>= flip writeRef a++stepTime :: Ref m r => Adaptive m r (TimeStamp m r)+stepTime = do+    readCurrentTime >>= inOL . flip OL.insert () >>= writeCurrentTime+    readCurrentTime++instance InM Changeable where+  inM m = Ch $ (inM m >>=)++instance InM Adaptive where+  inM m = Ad $ const (OL.inM m)++change (Mo (r,changeR,es)) a = do+    chg <- readRef changeR+    chg a++propagate = do+   let prop = do+        pq <- readPq+        case PQ.min pq of+          Nothing -> return ()+          Just ((reader,start,stop),pq') -> do+            writePq pq'+            unlessM (inOL (OL.deleted start)) $ do+                inOL (OL.spliceOut start stop)+                writeCurrentTime start+                reader+            prop+   now <- readCurrentTime+   prop+   writeCurrentTime now+++run m = OL.run $ do +   pq  <- newRef PQ.empty+   ct  <- OL.base >>= newRef+   deAd m (pq,ct)++inCh (Ch m) = do+   x <- newRef (error "inCh")+   m (writeRef x)+   readRef x++instance EqRef r => Eq (Modifiable m r a) where+   (Mo (r1,_,_)) == (Mo (r2,_,_)) = eqRef r1 r2++newMod = newModBy (==)++instance Ref m r => NewMod Changeable m r where+  newModBy c ch = inAd $ newModBy c ch++insertPQ :: Ref m r => +       r [ReComp m r] -> Adaptive m r ()+insertPQ esR = do+   es <- readRef esR+   pqR <- pqRef+   readRef pqR >>= ins es >>= writeRef pqR+  where+  ins []     pq = return pq+  ins (e:es) pq = PQ.insertM (\x y -> inOL $ +                              OL.order (startTime x) (startTime y))+                             e pq >>= ins es++instance Ref m r => NewMod Adaptive m r where+  newModBy cmp c = do+  m <- newRef (error "newMod")+  changeR <- newRef (error "changeR")+  es <- newRef []+  let writeFirst v = do+        writeRef m v+        now <- stepTime+        writeRef changeR (writeAgain now)+      writeAgain t v = do+        v' <- readRef m+        unless (cmp v' v) $ do+          writeRef m v+          insertPQ es+          writeRef es []+        writeCurrentTime t+  writeRef changeR writeFirst+  inCh $ do+    v <- c+    write <- readRef changeR+    inAd $ write v+  return (Mo (m, changeR, es))
+ Control/Monad/Adaptive/CircularList.hs view
@@ -0,0 +1,72 @@+-- -*- haskell-hugs-program-args: ("+." "-98") -*-++-- A monad of mutable circular lists.++module Control.Monad.Adaptive.CircularList(+  CircularList,+  circularList,+  val,+  update,+  next,+  previous,+  insert,+  delete) where++import Control.Monad.Adaptive.Ref++-- Export:+circularList :: Ref m r => a -> m (CircularList m r a)+val          :: Ref m r => CircularList m r a -> m a+next         :: Ref m r => CircularList m r a -> m (CircularList m r a)+update       :: Ref m r => CircularList m r a -> a -> m ()+previous     :: Ref m r => CircularList m r a -> m (CircularList m r a)+insert       :: Ref m r => CircularList m r a -> a -> m (CircularList m r a)+delete       :: Ref m r => CircularList m r a -> m ()++-- Local:++data CircularList m r a = CL (r (CircularList m r a,a,CircularList m r a))+                        | DummyCL (m a)++deCL (CL l) = l++circularList a = do+  r <- newRef undefined+  let l = CL r+  writeRef r (l,a,l)+  return l++get :: Ref m r => CircularList m r a -> +                  m (CircularList m r a, a,CircularList m r a)+get = readRef . deCL++set :: Ref m r => CircularList m r a -> +                  (CircularList m r a, a,CircularList m r a) -> m ()+set = writeRef . deCL++update l a = do+         (p,_,n) <- get l+         set l (p,a,n)++val l = (\ (p,a,n) -> a) `fmap` get l++next l = (\ (p,a,n) -> n) `fmap` get l++previous l = (\ (p,a,n) -> p) `fmap` get l++insert l a = do+  (p,b,n) <- get l+  n' <- CL `fmap` newRef (l,a,n)+  set l (p,b,n')+  nl <- next n'+  (_,nb,nn) <- get nl+  set nl (n',nb,nn)+  return n'+++delete l = do+  (p,_,n) <- get l+  (pp,a,_) <- get p+  set p (pp,a,n)+  (_,a',nn) <- get n+  set n (p,a',nn)
+ Control/Monad/Adaptive/MonadUtil.hs view
@@ -0,0 +1,10 @@+module Control.Monad.Adaptive.MonadUtil where++ifM :: Monad m => m Bool -> m a -> m a -> m a+ifM b a c = do b' <- b; if b' then a else c++whenM :: Monad m => m Bool -> m () -> m ()+whenM b a = ifM b a (return ())++unlessM :: Monad m => m Bool -> m () -> m ()+unlessM b a = ifM b (return ()) a
+ Control/Monad/Adaptive/OrderedList.hs view
@@ -0,0 +1,233 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}+-- A monad for manipulating ordered lists.  Follows the implementation+-- given in the appendix of O'Neill's and Burton's JFP paper, but+-- doesn't impose any fixed limit of the number of elements.++-- References:++-- Dietz and Sleator: "Two algorithms for maintaining order in a+-- list", in Proc. of 19th ACM Symposium of Theory of Computing, 1987.++-- O'Neill and Burton: "A New Method For Functional Arrays", Journal+-- of Functional Programming, vol7, no 5, September 1997.++module Control.Monad.Adaptive.OrderedList(+  Record,+  OrderedList,+  rval,+  next,+  order,+  delete,+  spliceOut,+  deleted,+  insert,+  base,+  run,+  inM,+  record+  ) where++import Monad(ap,unless)+import Control.Monad.Adaptive.MonadUtil+import Control.Monad.Adaptive.Ref+import Control.Monad.Adaptive.CircularList hiding (delete,insert,next,update)+import qualified Control.Monad.Adaptive.CircularList as CircularList++import System.IO.Unsafe(unsafePerformIO) -- for diagnostic++-- Export:+insert    :: Ref m r => Record m r a -> a -> OrderedList m r a (Record m r a)+next      :: Ref m r => Record m r a -> OrderedList m r a (Record m r a)+delete    :: Ref m r => Record m r a -> OrderedList m r a ()+spliceOut :: Ref m r => Record m r a -> Record m r a -> OrderedList m r a ()+deleted   :: Ref m r => Record m r a -> OrderedList m r a Bool+order     :: Ref m r => Record m r a -> Record m r a -> +                        OrderedList m r a Ordering+rval      :: Ref m r => Record m r a -> OrderedList m r a a+run       :: Ref m r => OrderedList m r a b -> m b+inM       :: Ref m r => m b -> OrderedList m r a b+base      :: Ref m r => OrderedList m r a (Record m r a)+++-- Local:++newtype Record m r a = Record (CircularList m r (Bool,Integer,a))+deR (Record r) = r++data OrderedList m r a b = OL ((r Integer,r Integer,Record m r a) -> m b)+deOL (OL f) = f++run l = do+    base <- Record `fmap` circularList (False,0,undefined)+    s <- newRef 0+    mr <- newRef m+    deOL l (mr,s,base)+  where +    m = 2^16++inM m = OL $ \e -> m++instance Ref m r => Monad (OrderedList m r a) where+  return a = inM (return a)+  (OL m) >>= f = OL $ \e -> m e >>= \a -> deOL (f a) e++instance Ref m r => Functor (OrderedList m r a) where +  fmap f m = m >>= return . f++instance Ref m r => Ref (OrderedList m r a) r where+  newRef v     = inM (newRef v)+  readRef r    = inM (readRef r)+  writeRef r v = inM (writeRef r v)++mop a o b = op2 o a b+op2 f a b = op1 f a `ap` b+op1 f a = return f `ap` a++instance Eq (OrderedList m r a b) where { }+instance Show (OrderedList m r a b) where { }++instance (Ref m r, Num b) => Num (OrderedList m r a b) where+  (+)         = op2 (+)+  (-)         = op2 (-)+  (*)         = op2 (*)+  negate      = op1 negate+  abs         = op1 abs+  signum      = op1 signum+  fromInteger = return . fromInteger+--  fromInt     = return . fromInt++instance Ord (OrderedList m r a b) where { }+instance (Ref m r, Real b) => Real (OrderedList m r a b) where { }+instance Enum (OrderedList m r a b) where { }++instance (Ref m r, Integral b) => Integral (OrderedList m r a b) where+  rem = op2 rem+  div = op2 div+  mod = op2 mod++base = OL $ \(m,n,b) -> return b++bigM :: Ref m r => OrderedList m r a Integer+bigM = OL $ \(m,n,b) -> readRef m++size :: Ref m r => OrderedList m r a Integer+size = OL $ \(m,n,b) -> readRef n++adjsize :: Ref m r => Integer -> OrderedList m r a ()+adjsize i = OL $ \(m,n,b) -> do s <- readRef n+                                writeRef n (s+i)++setSize :: Ref m r => Integer -> OrderedList m r a ()+setSize n' = OL $ \(m,n,b) -> writeRef n n'++record :: Ref m r => Record m r a -> OrderedList m r a (Bool,Integer,a)+record r = inM (val (deR r))++rval r = (\ (d,i,a) -> a) `fmap` record r++next r = Record `fmap` inM (CircularList.next (deR r))++s x = next x++-- label+l :: Ref m r => Record m r a -> OrderedList m r a Integer+l r = (\ (d,i,a) -> i) `fmap` record r++-- gap+g e f = (l f - l e) `mod` bigM++deleted r = (\ (d,i,a) -> d) `fmap` record r++lbase :: Ref m r => OrderedList m r a Integer+lbase = base >>= l++gstar :: Ref m r => Record m r a -> Record m r a -> OrderedList m r a Integer+gstar e f = ifM (mop (l e) (==) (l f))+             bigM+             (g e f)++order x y = do b <- base+               return (compare) `ap` g b x `ap` g b y++++update :: Ref m r => ((Bool,Integer)->(Bool,Integer)) -> +                     Record m r a -> OrderedList m r a ()+update f r = do+   (d,i,a) <- record r+   let (d',i') = f (d,i)+   inM (CircularList.update (deR r) (d',i',a))+   +delete r = unlessM (deleted r) $ do+             ifM (mop lbase (==) (l r))+               (error "OrderedList.delete on base element")+               (do inM (CircularList.delete (deR r))+                   update (\ (_,i) -> (True,i)) r+                   adjsize (-1)+                   checkinvariant)++spliceOut r s = next r >>= spl where+  spl r = do +    unlessM (mop lbase (==) (l r)) $+        whenM ((==LT) `fmap` order r s)+              (do r' <- next r+                  delete r+                  spl r')++increaseBigM :: Ref m r => OrderedList m r a ()+increaseBigM = do OL $ \(m,n,b) -> mapRef (*2) m++insert r a = do+  ifM (deleted r) +    (error "insert: deleted") $ do+    whenM (mop bigM (<=) (4*(size+1)*(size+1)))+      increaseBigM+    r' <- s r+    d <- gstar r r'+    unless (d > 1)+      (renumber r)+    li <- (l r + (gstar r r' `div` 2)) `mod` bigM+    inM (CircularList.insert (deR r) (False,li,a))+    adjsize 1+    checkinvariant+    next r++renumber :: Ref m r => Record m r a -> OrderedList m r a ()+renumber e = do+   let getj j e0 ej = do+          ifM (mop (g e0 ej) (>) (return (j * j)))+            (return (j,ej)) $ do+            ej' <- s ej+            ifM (mop (l ej') (==) (l e))+              (return (j,ej)) $ do+              getj (j+1) e0 ej'+   (j,sje) <- s e >>= getj 1 e+   d <- gstar e sje+   le <- l e+   m <- bigM+   let ren k ek | k == j     = return ()+                | otherwise  = do+          update (const (False,(le + ((k * d) `div` j)) `mod` m)) ek+          s ek >>= ren (k+1)+   s e >>= ren 1++checkinvariant :: Ref m r => OrderedList m r a ()+checkinvariant = return () -- prall >> base >>= inv+  where inv r = do+             r' <- s r+             unlessM (mop lbase (==) (l r')) $ do+               ifM (mop (order r r') (==) (return LT))+                   (inv r')+                   (error "invariant")+++prall :: Ref m r => OrderedList m r a ()+prall = uprint "prall:" >> base >>= pr where+  pr r = do+    x <- l r+    uprint (show x)+    r' <- s r+    unlessM (mop (base >>= order r') (==) (return EQ))+        (pr r')++uprint s = OL$ (\s' -> unsafePerformIO (putStrLn s) `seq` return ())
+ Control/Monad/Adaptive/PriorityQueue.hs view
@@ -0,0 +1,41 @@++-- A naive priority queue implementation, with an insert operation+-- that uses a monadic comparison operation.++module Control.Monad.Adaptive.PriorityQueue(+  PriorityQueue,+  empty,+  insert,+  insertM,+  min+  ) where++import Prelude hiding(min)++import qualified List(insert)+import Monad(ap)++-- Export:+empty   :: PriorityQueue a+insert  :: Ord a => a -> PriorityQueue a -> PriorityQueue a+insertM :: Monad m => +          (a -> a -> m Ordering) -> a -> PriorityQueue a -> m (PriorityQueue a)+min     :: PriorityQueue a -> Maybe (a, PriorityQueue a)++-- Local++newtype PriorityQueue a = PQ [a]++empty = PQ []++insert a (PQ l) = PQ (List.insert a l)+++insertM cmp a (PQ l) = return PQ `ap` ins l+  where ins [] = return [a]+        ins (b:l) = do o <- cmp a b+                       case o of LT -> return (a:b:l)+                                 _  -> return (b:) `ap` ins l++min (PQ []) = Nothing+min (PQ (x:xs)) = Just (x,PQ xs)
+ Control/Monad/Adaptive/Ref.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}+-- A class for monads with mutable references++module Control.Monad.Adaptive.Ref where++import Control.Monad.ST+import Data.IORef+import Data.STRef++class EqRef r where+    eqRef :: r a -> r a -> Bool++class (EqRef r, Functor m, Monad m) => Ref m r | m -> r where+  newRef   :: a -> m (r a)+  readRef  :: r a -> m a+  writeRef :: r a -> a -> m ()++instance EqRef (STRef s) where eqRef = (==)++instance Ref (ST s) (STRef s) where+  newRef = newSTRef+  readRef = readSTRef+  writeRef = writeSTRef++instance EqRef IORef where eqRef = (==)++instance Ref IO IORef where+  newRef = newIORef+  readRef = readIORef+  writeRef = writeIORef++mapRef :: Ref m r => (a -> a) -> r a -> m ()+mapRef f r = readRef r >>= writeRef r . f
− Data/Adaptive.hs
@@ -1,287 +0,0 @@-{-  -    This file is part of Adaptive.--    Adaptive is free software: you can redistribute it and/or modify-    it under the terms of the GNU Lesser General Public License as published by-    the Free Software Foundation, either version 3 of the License, or-    (at your option) any later version.--    Adaptive is distributed in the hope that it will be useful,-    but WITHOUT ANY WARRANTY; without even the implied warranty of-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the-    GNU Lesser General Public License for more details.--    You should have received a copy of the GNU Lesser General Public License-    along with Adaptive.  If not, see <http://www.gnu.org/licenses/>.--}--{-# LANGUAGE FlexibleInstances, BangPatterns, UnboxedTuples #-}-{-# OPTIONS_GHC -fno-excess-precision -fno-spec-constr #-}--- {-# OPTIONS_GHC -fglasgow-exts -fno-excess-precision -fno-spec-constr #-}--- use SSE to avoid the excess precision of the 387 FPU--- {-# OPTIONS_GHC -fvia-C -optc-O -optc-ffast-math -optc-mfpmath=sse -optc-msse #-}--- {-# OPTIONS_GHC -fllvm -optlc-mattr=+sse4a -optlc--disable-excess-fp-precision #-}---- | Based on Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates, Jonathan Richard Shewchuk, 1997-module Data.Adaptive (Adaptive(..), fromFloatingPoint, approx, approx', approxFast, splitter, epsilon) where--import Data.List-import Data.Bits-import Data.Ratio--type FloatT = Double----mergeBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a]-mergeBy _ xs [] = xs-mergeBy _ [] ys = ys-mergeBy cmp (x:xs) (y:ys) = case cmp x y of-                              GT -> y : mergeBy cmp (x:xs) ys-                              _ -> x : mergeBy cmp xs (y:ys)--newtype Adaptive a = Adaptive [a]--instance (Show a, RealFloat a) => Show (Adaptive a) where-  showsPrec n x = showParen (n > 6 && x < 0) $ showsPrec 0 (approx x) . ('~':)--------------------------- approximate instances ---------------------------liftAdaptive1 f = fromFloatingPoint . f . approxFast-liftAdaptive2 f x y = fromFloatingPoint $ approxFast x `f` approxFast y--instance (RealFloat a, Real a) => Real (Adaptive a) where-  toRational = toRational . approxFast--instance (RealFloat a, Floating a) => Floating (Adaptive a) where-  pi = fromFloatingPoint pi-  exp = liftAdaptive1 exp-  sqrt = sqrtA-  log = liftAdaptive1 log-  (**) = liftAdaptive2 (**)-  logBase = liftAdaptive2 logBase-  sin = liftAdaptive1 sin-  tan = liftAdaptive1 tan-  cos = liftAdaptive1 cos-  asin = liftAdaptive1 asin-  atan = liftAdaptive1 atan-  acos = liftAdaptive1 acos-  sinh = liftAdaptive1 sinh-  tanh = liftAdaptive1 tanh-  cosh = liftAdaptive1 cosh-  asinh = liftAdaptive1 asinh-  atanh = liftAdaptive1 atanh-  acosh = liftAdaptive1 acosh--instance (RealFloat a) => RealFloat (Adaptive a) where-  floatRadix = floatRadix . approxFast-  floatDigits = floatDigits . approxFast-  floatRange = floatRange . approxFast-  decodeFloat = decodeFloat . approxFast-  encodeFloat s r = fromFloatingPoint (encodeFloat s r)-  exponent = exponent . approxFast-  significand = liftAdaptive1 significand-  scaleFloat x = liftAdaptive1 (scaleFloat x)-  isNaN = isNaN . approxFast-  isInfinite = isInfinite . approxFast-  isDenormalized = isDenormalized . approxFast-  isNegativeZero = isNegativeZero . approxFast-  isIEEE = isIEEE . approxFast-  atan2 = liftAdaptive2 atan2--instance (RealFloat a, RealFrac a) => RealFrac (Adaptive a) where-  properFraction x = (y, fromFloatingPoint x')-    where (y, x') = properFraction (approxFast x)-----------------------------------------------------------------------------instance (Num a, RealFloat a) => Eq (Adaptive a) where-  {-# SPECIALIZE instance Eq (Adaptive FloatT) #-}-  a == b | null x = True-         | otherwise = False-    where Adaptive x = a - b--instance (Num a, RealFloat a) => Ord (Adaptive a) where-  {-# SPECIALIZE instance Ord (Adaptive FloatT) #-}-  compare a b | null x = EQ-              | head x > 0 = GT-              | otherwise = LT-    where Adaptive x = a - b--instance (Num a, RealFloat a) => Num (Adaptive a) where-  {-# SPECIALIZE instance Num (Adaptive FloatT) #-}-  Adaptive x + Adaptive y = Adaptive . compress $ fastExpSum x y-  Adaptive x - Adaptive y = Adaptive x + Adaptive (map negate y)-  Adaptive x * Adaptive y = Adaptive $ expProd x y-  negate (Adaptive x) = Adaptive (map negate x)-  abs (Adaptive []) = Adaptive []-  abs (Adaptive x) | head x < 0 = Adaptive (map negate x)-                   | otherwise = Adaptive x-  signum (Adaptive []) = Adaptive []-  signum (Adaptive (x:_)) = Adaptive [signum x]-  fromInteger 0 = Adaptive []-  fromInteger x = Adaptive [fromInteger x]--instance (RealFloat a, Fractional a) => Fractional (Adaptive a) where-  {-# SPECIALIZE instance Fractional (Adaptive FloatT) #-}-  fromRational r = fromIntegral (numerator r) / fromIntegral (denominator r)-  a / b = Adaptive $ a `divA` b--{-# SPECIALIZE divA :: Adaptive FloatT -> Adaptive FloatT -> [FloatT] #-}-divA x y | d == 0 = []-         | e == 0 || abs e >= abs x = [d]-         | otherwise = d : divA e y-  where d = approxFast x / approxFast y-        e = x - fromFloatingPoint d * y---- | Use Babylonian method to calculate corrections to built in sqrt-{-# SPECIALIZE sqrtA :: Adaptive FloatT -> Adaptive FloatT #-}-sqrtA x = r + bab r-  where r = liftAdaptive1 sqrt x-        bab e | c == 0 = 0-              | otherwise = c + bab (e + c)-          where c = (x / e - e) / 2--{-# SPECIALIZE epsilon :: FloatT #-}-epsilon :: (RealFloat a) => a-epsilon = x-  where x = scaleFloat (- floatDigits x) 1--{-# SPECIALIZE splitter :: FloatT #-}-splitter :: (RealFloat a) => a-splitter = s-  where s = scaleFloat ((floatDigits s + 1) `shiftR` 1) 1 + 1---- {-# INLINE fromFloatingPoint #-}-{-# SPECIALIZE fromFloatingPoint :: FloatT -> Adaptive FloatT #-}-fromFloatingPoint :: (RealFloat a) => a -> Adaptive a-fromFloatingPoint 0 = Adaptive []-fromFloatingPoint x = Adaptive [x]--{-# INLINE approx #-}--- {-# SPECIALIZE approx :: Adaptive FloatT -> FloatT #-}-approx :: (RealFloat a, Ord a) => Adaptive a -> a-approx (Adaptive []) = 0-approx (Adaptive (x:xs)) = foldr (+) x . takeWhile ((> x*epsilon).abs) $ xs--{-# INLINE approx' #-}--- {-# SPECIALIZE approx' :: Adaptive FloatT -> FloatT #-}-approx' :: (Real a, RealFloat b) => Adaptive a -> b-approx' (Adaptive []) = 0-approx' (Adaptive (x:xs)) = foldr (+) x' .-                            takeWhile ((> x' * epsilon) . abs) .-                            map realToFrac $ xs-  where x' = realToFrac x---- {-# INLINE approxFast #-}-{-# SPECIALIZE approxFast :: Adaptive FloatT -> FloatT #-}-approxFast :: (Num a) => Adaptive a -> a-approxFast (Adaptive []) = 0-approxFast (Adaptive (x:_)) = x---- |a| >= [b]-{-# INLINE fastTwoSum #-}---{-# SPECIALIZE fastTwoSum :: FloatT -> FloatT -> (# FloatT, FloatT #) #-}-fastTwoSum :: (Num a) => a -> a -> (# a, a #)-fastTwoSum a b = (# x, y #)-  where x = a + b-        b' = x - a-        y = b - b'--{-# INLINE twoSum #-}---{-# SPECIALIZE twoSum :: FloatT -> FloatT -> (# FloatT, FloatT #) #-}-twoSum :: (Num a) => a -> a -> (# a, a #)-twoSum !a !b = (# x, y #)-  where !x = a + b-        !b' = x - a-        !a' = x - b'-        !br = b - b'-        !ar = a - a'-        !y = ar + br--{--{-# INLINE twoSum' #-}---{-# SPECIALIZE twoSum' :: FloatT -> FloatT -> (FloatT, FloatT) #-}-twoSum' :: (Num a) => a -> a -> (a, a)-twoSum' a b = (x, y)-  where x = a + b-        b' = x - a-        a' = x - b'-        br = b - b'-        ar = a - a'-        y = ar + br----{-# SPECIALIZE growExp :: FloatT -> [FloatT] -> [FloatT] #-}-growExp :: (Num a) => a -> [a] -> [a]-growExp b es = filter (/= 0) . uncurry (:) . mapAccumR twoSum' b $ es----{-# SPECIALIZE expSum :: [FloatT] -> [FloatT] -> [FloatT] #-}-expSum :: (Num a) => [a] -> [a] -> [a]-expSum = foldr growExp--}--{-# SPECIALIZE fastExpSum :: [FloatT] -> [FloatT] -> [FloatT] #-}-fastExpSum :: (RealFloat a) => [a] -> [a] -> [a]-fastExpSum [] x = x-fastExpSum x [] = x-fastExpSum e f = filter (/= 0) (q:hs)-  where g = mergeBy cmp e f-        cmp x y = compare (exponent y) (exponent x)-        (# q, hs #) = mapAccumR1 twoSum g----mapAccumR1 :: (t -> t -> (# t, a #)) -> [t] -> (# t, [a] #)-mapAccumR1 f [x] = (# x, [] #)-mapAccumR1 f (x:xs) = (# a', y:xs' #)-  where (# a, xs' #) = mapAccumR1 f xs-        (# a', y #) = f a x----{-# INLINE split #-}---{-# SPECIALIZE split :: FloatT -> (# FloatT, FloatT #) #-}---split :: (RealFloat a) => a -> (# a, a #)-split !a = (# ah, al #)-  where !c = splitter * a-        !ab = c - a-        !ah = c - ab-        !al = a - ah----{-# INLINE twoProd #-}---{-# SPECIALIZE twoProd :: FloatT -> FloatT -> (# FloatT, FloatT #) #-}---twoProd :: (RealFloat a) => a -> a -> (# a, a #)-twoProd !a !b = (# x, y #)-  where !x = a * b-        (# !ah, !al #) = split a-        (# !bh, !bl #) = split b-        !err = x - ah * bh - al * bh - ah * bl-        !y = al * bl - err----{-# INLINE scaleExp #-}---{-# SPECIALIZE scaleExp :: FloatT -> [FloatT] -> [FloatT] #-}---scaleExp :: (RealFloat a) => a -> [a] -> [a]-scaleExp _ [] = []-scaleExp b es = filter (/= 0) . (uncurry (:)) . foldr f (q0, [h0]) . init $ es-  where (# q0, h0 #) = twoProd (last es) b-        f e (q, h) = (q'', h2 : h1 : h)-          where (# th, tl #) = twoProd e b-                (# q', h1 #) = twoSum q tl-                (# q'', h2 #) = fastTwoSum th q'----{-# INLINE expProd #-}---{-# SPECIALIZE expProd :: [FloatT] -> [FloatT] -> [FloatT] #-}---expProd :: (RealFloat a) => [a] -> [a] -> [a]-expProd [] _ = []-expProd _ [] = []-expProd x [y] = scaleExp y x-expProd [x] y = scaleExp x y-expProd (x:xs) ys = foldl' f (scaleExp x ys) xs-  where f h e = fastExpSum h . scaleExp e $ ys----{-# SPECIALIZE compress :: [FloatT] -> [FloatT] #-}---compress :: (Num a) => [a] -> [a]-compress e = comp up . comp down $ e-  where comp _ [] = []-        comp _ [x] = [x]-        comp f (x:xs) = uncurry (:) . foldl' f (x, []) $ xs-        down (q, h) e | ql /= 0 = (ql, qu:h)-                      | otherwise = (qu, h)-          where (# qu, ql #) = fastTwoSum q e-        up (q, h) e | ql /= 0 = (qu, ql:h) -- error on pg. 28, line 14: Q should be q-                    | otherwise = (qu, h)-          where (# qu, ql #) = fastTwoSum e q
LICENSE view
@@ -1,165 +1,29 @@-                  GNU LESSER GENERAL PUBLIC LICENSE-                       Version 3, 29 June 2007-- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>- Everyone is permitted to copy and distribute verbatim copies- of this license document, but changing it is not allowed.---  This version of the GNU Lesser General Public License incorporates-the terms and conditions of version 3 of the GNU General Public-License, supplemented by the additional permissions listed below.--  0. Additional Definitions. --  As used herein, "this License" refers to version 3 of the GNU Lesser-General Public License, and the "GNU GPL" refers to version 3 of the GNU-General Public License.--  "The Library" refers to a covered work governed by this License,-other than an Application or a Combined Work as defined below.--  An "Application" is any work that makes use of an interface provided-by the Library, but which is not otherwise based on the Library.-Defining a subclass of a class defined by the Library is deemed a mode-of using an interface provided by the Library.--  A "Combined Work" is a work produced by combining or linking an-Application with the Library.  The particular version of the Library-with which the Combined Work was made is also called the "Linked-Version".--  The "Minimal Corresponding Source" for a Combined Work means the-Corresponding Source for the Combined Work, excluding any source code-for portions of the Combined Work that, considered in isolation, are-based on the Application, and not on the Linked Version.--  The "Corresponding Application Code" for a Combined Work means the-object code and/or source code for the Application, including any data-and utility programs needed for reproducing the Combined Work from the-Application, but excluding the System Libraries of the Combined Work.--  1. Exception to Section 3 of the GNU GPL.--  You may convey a covered work under sections 3 and 4 of this License-without being bound by section 3 of the GNU GPL.--  2. Conveying Modified Versions.--  If you modify a copy of the Library, and, in your modifications, a-facility refers to a function or data to be supplied by an Application-that uses the facility (other than as an argument passed when the-facility is invoked), then you may convey a copy of the modified-version:--   a) under this License, provided that you make a good faith effort to-   ensure that, in the event an Application does not supply the-   function or data, the facility still operates, and performs-   whatever part of its purpose remains meaningful, or--   b) under the GNU GPL, with none of the additional permissions of-   this License applicable to that copy.--  3. Object Code Incorporating Material from Library Header Files.--  The object code form of an Application may incorporate material from-a header file that is part of the Library.  You may convey such object-code under terms of your choice, provided that, if the incorporated-material is not limited to numerical parameters, data structure-layouts and accessors, or small macros, inline functions and templates-(ten or fewer lines in length), you do both of the following:--   a) Give prominent notice with each copy of the object code that the-   Library is used in it and that the Library and its use are-   covered by this License.--   b) Accompany the object code with a copy of the GNU GPL and this license-   document.--  4. Combined Works.--  You may convey a Combined Work under terms of your choice that,-taken together, effectively do not restrict modification of the-portions of the Library contained in the Combined Work and reverse-engineering for debugging such modifications, if you also do each of-the following:--   a) Give prominent notice with each copy of the Combined Work that-   the Library is used in it and that the Library and its use are-   covered by this License.--   b) Accompany the Combined Work with a copy of the GNU GPL and this license-   document.--   c) For a Combined Work that displays copyright notices during-   execution, include the copyright notice for the Library among-   these notices, as well as a reference directing the user to the-   copies of the GNU GPL and this license document.--   d) Do one of the following:--       0) Convey the Minimal Corresponding Source under the terms of this-       License, and the Corresponding Application Code in a form-       suitable for, and under terms that permit, the user to-       recombine or relink the Application with a modified version of-       the Linked Version to produce a modified Combined Work, in the-       manner specified by section 6 of the GNU GPL for conveying-       Corresponding Source.--       1) Use a suitable shared library mechanism for linking with the-       Library.  A suitable mechanism is one that (a) uses at run time-       a copy of the Library already present on the user's computer-       system, and (b) will operate properly with a modified version-       of the Library that is interface-compatible with the Linked-       Version. --   e) Provide Installation Information, but only if you would otherwise-   be required to provide such information under section 6 of the-   GNU GPL, and only to the extent that such information is-   necessary to install and execute a modified version of the-   Combined Work produced by recombining or relinking the-   Application with a modified version of the Linked Version. (If-   you use option 4d0, the Installation Information must accompany-   the Minimal Corresponding Source and Corresponding Application-   Code. If you use option 4d1, you must provide the Installation-   Information in the manner specified by section 6 of the GNU GPL-   for conveying Corresponding Source.)--  5. Combined Libraries.--  You may place library facilities that are a work based on the-Library side by side in a single library together with other library-facilities that are not Applications and are not covered by this-License, and convey such a combined library under terms of your-choice, if you do both of the following:--   a) Accompany the combined library with a copy of the same work based-   on the Library, uncombined with any other library facilities,-   conveyed under the terms of this License.+Copyright 2002-2008 Magnus Carlsson <magnus@galois.com>+All rights reserved. -   b) Give prominent notice with the combined library that part of it-   is a work based on the Library, and explaining where to find the-   accompanying uncombined form of the same work.+Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met: -  6. Revised Versions of the GNU Lesser General Public License.+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer. -  The Free Software Foundation may publish revised and/or new versions-of the GNU Lesser General Public License from time to time. Such new-versions will be similar in spirit to the present version, but may-differ in detail to address new problems or concerns.+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. -  Each version is given a distinguishing version number. If the-Library as you received it specifies that a certain numbered version-of the GNU Lesser General Public License "or any later version"-applies to it, you have the option of following the terms and-conditions either of that published version or of any later version-published by the Free Software Foundation. If the Library as you-received it does not specify a version number of the GNU Lesser-General Public License, you may choose any version of the GNU Lesser-General Public License ever published by the Free Software Foundation.+3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission. -  If the Library as you received it specifies that a proxy can decide-whether future versions of the GNU Lesser General Public License shall-apply, that proxy's public statement of acceptance of any version is-permanent authorization for you to choose that version for the-Library.+THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ README view
@@ -0,0 +1,46 @@+Adaptive version 0.22 2008-07-14+================================++This is a minor update to Adaptive version 0.21 to make it work with+recent versions of GHC and Hugs. Adaptive is now cabalized, and any+problems with the packaging is my fault, not Magnus.++Peter A. Jonsson, pj@csee.ltu.se+++Adaptive version 0.21  2005-07-09+=================================++This is a Haskell (plus some extensions) implementation of a library+for incremental computing.  It closely follows the implementation in+the nice POPL 2002 paper "Adaptive Functional Programming", by Umut+Acar, Guy Blelloch and Bob Harper.  As of writing, their paper can be+found at++      http://ttic.uchicago.edu/~umut/papers/popl02.html++However, this Haskell library provides a monadic interface, which+doesn't need the "write" operation or the "destination" type.  In+addition, the monadic types enforce correct usage, which means that a+modifiable variable must be defined before it can be used.  This is+achieved within Haskell's type system plus some popular extensions+(multi-parameter classes and functional dependencies).++The library is parameterised over any monad that has references (such+as IO and ST).  This means that it should be possible to put it on top+of e.g. many GUI monads too.++There is a small demo program of a classical incremental computation+problem: a spreadsheet.  Try it by typing++   runhugs -98 spreadsheet.hs++and type, say ++  c0 <Return> Cell c1 <Return> c1 <Return> Const 42 <Return>.++This has been tested with the Hugs September 2006 version.++Feedback is welcome!++Magnus Carlsson, magnus@galois.com
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
+ Setup.lhs view
@@ -0,0 +1,4 @@+#! /usr/bin/env runhaskell++> import Distribution.Simple+> main = defaultMain
+ spreadsheet.hs view
@@ -0,0 +1,124 @@+-- -*- haskell-hugs-program-args: ("+." "-98") -*-+{-# LANGUAGE FlexibleContexts #-}++-- A demo program of the Adaptive library, implementing a simple+-- spreadsheet.  Requires a VT100-like terminal to work.  Expressions+-- have to be entered according to the Expr datatype.++-- Magnus Carlsson, magnus@cse.ogi.edu++import Control.Monad.Adaptive+import Data.Char+import Control.Monad.Adaptive.Ref+import Monad(ap,when)+import Data.IORef(IORef)+import System++type InIO m a = m IO IORef a+type IOMod a = InIO Modifiable a++data CellRef = CR String (IOMod Integer) deriving Eq+instance Show CellRef where show (CR s _) = s++data Expr c = Const Integer | Add (Expr c) (Expr c) | Cell c+  deriving (Eq,Read,Show)++eval :: Expr CellRef -> InIO Changeable Integer+eval (Const i)       = return i+eval (Add e1 e2)     = return (+) `ap` eval e1 `ap` eval e2+eval (Cell (CR _ n)) = readMod n++memo ma = readMod =<< newMod ma++instance Eq (a -> b) where a == b = False++ap' mf ma = do+  m <- newMod mf+  a <- memo ma+  f <- readMod m+  return (f a)++newCell :: NewMod m IO IORef => +           String -> InIO m (IOMod (Expr CellRef), CellRef)+newCell s = do+     c <- newMod (return (Const 0))+     v <- newMod $ readMod c >>= eval+     return (c,CR s v)++newCell' n = do+    let s = "c" ++ show n+    inM $ prAt (n+2) 0 3 (s++": ")+    a@(c,CR s v) <- newCell s+    newMod $ readMod v >>= inM . prAt (n+2) 5 10 . show+    newMod $ readMod c >>= inM . prAt (n+2) 15 40 . show+    return (s,a)++prAt l c w s = putStr (pos l c ++ replicate w ' ' ++ pos l c++s)+esc = ("\ESC["++)+pos l c = esc (show l++";"++show c++"H")+clear = pos 0 0 ++ esc "J"+cleareol = esc "K"++readPrompt c s = do prAt 20 c 0 (s++"> "++ cleareol)+                    s <- getLine+                    when (s == "quit") $ exitWith ExitSuccess+                    return s++msg s = prAt 19 0 0 (s ++ cleareol)++prompt env = inM p where+   p = do s <- readPrompt 0 "Cell"+          case lookup s env of+            Nothing -> do msg ("Cell " ++ show s ++ " not found")+                          p+            Just (c,v) -> do let r = do s <- readPrompt 10 "Expr"+                                        case reads s of +                                          [(e,"")] -> msg "" >> return (c,e)+                                          _ -> do msg "Syntax error"+                                                  r+                             r++data CellName = CN String+instance Read CellName where readsPrec _ s = [(CN $ takeWhile isAlphaNum s',+                                               dropWhile isAlphaNum s')]+                                  where s' = dropWhile isSpace s++instance Show CellName where show (CN s) = s++subst m env (Const i)     = Const i+subst m env (Add e1 e2)   = Add (subst m env e1) (subst m env e2)+subst m env (Cell (CN s)) = Cell $ case lookup s env of+                                            Nothing    -> m+                                            Just (c,v) -> v++main :: IO ()+main = run $ do+     inM $ putStr clear+     env <- mapM newCell' [0..9]+     m0 <- CR "?" `fmap` newMod (return 0)+     let loop = do (c,e) <- prompt env+                   let e' = subst m0 env e+                   change c e'+                   propagate+                   loop+     loop++-- small non-interactive example++newCellPr s = do+     a@(c,CR s v) <- newCell s+     newMod $ do e <- readMod c+                 x <- readMod v+                 inM $ putStrLn (s++" = "++show e ++ " = " ++ show x)+     return a++test = run $ do+     [(c1,v1),(c2,v2)] <- mapM newCellPr ["c1","c2"]+     change c1 (Const 10)+     change c2 (Add (Cell v1) (Const 5))+     inM (putStrLn "Propagate") >> propagate+     change c1 (Add (Cell v2) (Const 4))+     change c2 (Const 1)+     inM (putStrLn "Propagate") >> propagate+     change c2 (Const 2)+     inM (putStrLn "Propagate") >> propagate