packages feed

dunai 0.0.1.0 → 0.1.0.0

raw patch · 20 files changed

+1452/−31 lines, 20 filesdep +directorydep +filepathdep +hlintdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: directory, filepath, hlint, process, regex-posix, transformers, transformers-base

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Control.Monad.Trans.MStreamF: catchMaybe :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a b -> MStreamF m a b
+ Control.Monad.Trans.MStreamF: catchS :: Monad m => MStreamF (ExceptT e m) a b -> (e -> MStreamF m a b) -> MStreamF m a b
+ Control.Monad.Trans.MStreamF: exceptS :: Monad m => MStreamF (ExceptT e m) a b -> MStreamF m a (Either e b)
+ Control.Monad.Trans.MStreamF: exit :: Monad m => MStreamF (MaybeT m) a b
+ Control.Monad.Trans.MStreamF: exitIf :: Monad m => MStreamF (MaybeT m) Bool ()
+ Control.Monad.Trans.MStreamF: exitWhen :: Monad m => (a -> Bool) -> MStreamF (MaybeT m) a a
+ Control.Monad.Trans.MStreamF: inExceptT :: Monad m => MStreamF (ExceptT e m) (ExceptT e m a) a
+ Control.Monad.Trans.MStreamF: inMaybeT :: Monad m => MStreamF (MaybeT m) (Maybe a) a
+ Control.Monad.Trans.MStreamF: lifterS :: (Monad m, Monad m1) => ((a1 -> m1 (b1, MStreamF m1 a1 b1)) -> a -> m (b, MStreamF m1 a1 b1)) -> MStreamF m1 a1 b1 -> MStreamF m a b
+ Control.Monad.Trans.MStreamF: mapMaybeS :: Monad m => MStreamF m a b -> MStreamF m (Maybe a) (Maybe b)
+ Control.Monad.Trans.MStreamF: maybeExit :: Monad m => MStreamF (MaybeT m) (Maybe a) a
+ Control.Monad.Trans.MStreamF: readerS :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b
+ Control.Monad.Trans.MStreamF: readerS' :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b
+ Control.Monad.Trans.MStreamF: runMaybeS :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)
+ Control.Monad.Trans.MStreamF: runMaybeS'' :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)
+ Control.Monad.Trans.MStreamF: runRWSS :: (Functor m, Monad m, Monoid w) => MStreamF (RWST r w s m) a b -> MStreamF m (r, s, a) (w, s, b)
+ Control.Monad.Trans.MStreamF: runReaderS :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b
+ Control.Monad.Trans.MStreamF: runReaderS' :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b
+ Control.Monad.Trans.MStreamF: runReaderS'' :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b
+ Control.Monad.Trans.MStreamF: runReaderS_ :: Monad m => MStreamF (ReaderT s m) a b -> s -> MStreamF m a b
+ Control.Monad.Trans.MStreamF: runStateS :: Monad m => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)
+ Control.Monad.Trans.MStreamF: runStateS' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)
+ Control.Monad.Trans.MStreamF: runStateS'' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)
+ Control.Monad.Trans.MStreamF: runStateS''' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)
+ Control.Monad.Trans.MStreamF: runStateS_ :: Monad m => MStreamF (StateT s m) a b -> s -> MStreamF m a (s, b)
+ Control.Monad.Trans.MStreamF: runStateS__ :: Monad m => MStreamF (StateT s m) a b -> s -> MStreamF m a b
+ Control.Monad.Trans.MStreamF: runWriterS :: Monad m => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)
+ Control.Monad.Trans.MStreamF: runWriterS' :: (Monoid s, Functor m, Monad m) => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)
+ Control.Monad.Trans.MStreamF: runWriterS'' :: (Monoid s, Functor m, Monad m) => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)
+ Control.Monad.Trans.MStreamF: sequenceS :: Monad m => [MStreamF m a b] -> MStreamF (ListT m) a b
+ Control.Monad.Trans.MStreamF: stateS :: Monad m => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b
+ Control.Monad.Trans.MStreamF: stateS' :: (Functor m, Monad m) => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b
+ Control.Monad.Trans.MStreamF: throwMaybe :: Monad m => MStreamF (ExceptT e m) (Maybe e) (Maybe a)
+ Control.Monad.Trans.MStreamF: throwOn :: Monad m => e -> MStreamF (ExceptT e m) Bool ()
+ Control.Monad.Trans.MStreamF: throwOn' :: Monad m => MStreamF (ExceptT e m) (Bool, e) ()
+ Control.Monad.Trans.MStreamF: throwOnCond :: Monad m => (a -> Bool) -> e -> MStreamF (ExceptT e m) a a
+ Control.Monad.Trans.MStreamF: throwOnCondM :: Monad m => (a -> m Bool) -> e -> MStreamF (ExceptT e m) a a
+ Control.Monad.Trans.MStreamF: throwS :: Monad m => MStreamF (ExceptT e m) e a
+ Control.Monad.Trans.MStreamF: transG :: (Monad m1, Monad m2) => (a2 -> m1 a1) -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, Maybe c)) -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2
+ Control.Monad.Trans.MStreamF: transG1 :: (Monad m1, Functor m2, Monad m2) => (a2 -> m1 a1) -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c)) -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2
+ Control.Monad.Trans.MStreamF: transS :: (Monad m1, Monad m2) => (a2 -> m1 a1) -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c)) -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2
+ Control.Monad.Trans.MStreamF: type Id a = a
+ Control.Monad.Trans.MStreamF: type ReaderUnwrapper s m = Unwrapper (ReaderT s m) m ((,) s) Id
+ Control.Monad.Trans.MStreamF: type ReaderWrapper s m = Wrapper (ReaderT s m) m ((,) s) Id
+ Control.Monad.Trans.MStreamF: type Unwrapper m1 m2 t1 t2 = forall a b. (a -> m1 (t2 b)) -> (t1 a -> m2 b)
+ Control.Monad.Trans.MStreamF: type Wrapper m1 m2 t1 t2 = forall a b. (t1 a -> m2 b) -> (a -> m1 (t2 b))
+ Control.Monad.Trans.MStreamF: untilE :: Monad m => MStreamF m a b -> MStreamF m b (Maybe e) -> MStreamF (ExceptT e m) a b
+ Control.Monad.Trans.MStreamF: untilMaybe :: Monad m => MStreamF m a b -> MStreamF m b Bool -> MStreamF (MaybeT m) a b
+ Control.Monad.Trans.MStreamF: unwrapMSFWriterT :: (Monad m, Functor m) => (a -> WriterT s m (b, ct)) -> a -> m ((s, b), ct)
+ Control.Monad.Trans.MStreamF: unwrapReaderT :: (a -> ReaderT s m b) -> (s, a) -> m b
+ Control.Monad.Trans.MStreamF: widthFirst :: (Functor m, Monad m) => MStreamF (ListT m) a b -> MStreamF m a [b]
+ Control.Monad.Trans.MStreamF: wrapMSFWriterT :: (Monoid s, Monad m) => (a -> m ((s, b), ct)) -> a -> WriterT s m (b, ct)
+ Control.Monad.Trans.MStreamF: wrapReaderT :: ((s, a) -> m b) -> a -> ReaderT s m b
+ Control.Monad.Trans.MStreamF: writerS :: (Monad m, Monoid s) => MStreamF m a (s, b) -> MStreamF (WriterT s m) a b
+ Control.Monad.Trans.MStreamF: writerS' :: (Monad m, Monoid s) => MStreamF m a (s, b) -> MStreamF (WriterT s m) a b
+ Control.Monad.Trans.MStreamF: writerS'' :: (Monad m, Monoid w) => MStreamF m a (w, b) -> MStreamF (WriterT w m) a b
+ Data.MonadicStreamFunction: (>>>^) :: MonadBase m1 m2 => MStreamF m2 a b -> MStreamF m1 b c -> MStreamF m2 a c
+ Data.MonadicStreamFunction: (^>>>) :: MonadBase m1 m2 => MStreamF m1 a b -> MStreamF m2 b c -> MStreamF m2 a c
+ Data.MonadicStreamFunction: andThen :: Monad m => MStreamF m a (b, Maybe ()) -> MStreamF m a b -> MStreamF m a b
+ Data.MonadicStreamFunction: count :: (Num n, Monad m) => MStreamF m () n
+ Data.MonadicStreamFunction: iPost :: Monad m => b -> MStreamF m a b -> MStreamF m a b
+ Data.MonadicStreamFunction: insert :: Monad m => MStreamF m (m a) a
+ Data.MonadicStreamFunction: instance GHC.Base.Applicative m => GHC.Base.Applicative (Data.MonadicStreamFunction.Core.MStreamF m r)
+ Data.MonadicStreamFunction: instance GHC.Base.Functor m => GHC.Base.Functor (Data.MonadicStreamFunction.Core.MStreamF m r)
+ Data.MonadicStreamFunction: liftMStreamF_ :: Monad m => m b -> MStreamF m a b
+ Data.MonadicStreamFunction: mapMStreamF :: Monad m => MStreamF m a b -> MStreamF m [a] [b]
+ Data.MonadicStreamFunction: next :: Monad m => b -> MStreamF m a b -> MStreamF m a b
+ Data.MonadicStreamFunction: pauseOn :: Show a => (a -> Bool) -> String -> MStreamF IO a a
+ Data.MonadicStreamFunction: pauseOnGeneral :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MStreamF m a a
+ Data.MonadicStreamFunction: repeatedly :: Monad m => (a -> a) -> a -> MStreamF m () a
+ Data.MonadicStreamFunction: sum :: (Monoid n, Monad m) => MStreamF m n n
+ Data.MonadicStreamFunction: sumFrom :: (Monoid n, Monad m) => n -> MStreamF m n n
+ Data.MonadicStreamFunction: trace :: Show a => String -> MStreamF IO a a
+ Data.MonadicStreamFunction: traceGeneral :: (Monad m, Show a) => (String -> m ()) -> String -> MStreamF m a a
+ Data.MonadicStreamFunction: type MStream m a = MStreamF m () a
+ Data.MonadicStreamFunction: unfold :: Monad m => (a -> (b, a)) -> a -> MStreamF m () b
+ Data.MonadicStreamFunction: untilS :: Monad m => MStreamF m a b -> MStreamF m b Bool -> MStreamF m a (b, Maybe ())
+ Data.MonadicStreamFunction: withSideEffect :: Monad m => (a -> m b) -> MStreamF m a a
+ Data.MonadicStreamFunction: withSideEffect_ :: Monad m => m b -> MStreamF m a a
+ Data.MonadicStreamFunction.ArrowChoice: instance GHC.Base.Monad m => Control.Arrow.ArrowChoice (Data.MonadicStreamFunction.Core.MStreamF m)
+ Data.MonadicStreamFunction.ArrowLoop: instance (GHC.Base.Monad m, Control.Monad.Fix.MonadFix m) => Control.Arrow.ArrowLoop (Data.MonadicStreamFunction.Core.MStreamF m)
+ Data.MonadicStreamFunction.ArrowPlus: instance (GHC.Base.Monad m, GHC.Base.MonadPlus m) => Control.Arrow.ArrowPlus (Data.MonadicStreamFunction.Core.MStreamF m)
+ Data.MonadicStreamFunction.ArrowPlus: instance (GHC.Base.Monad m, GHC.Base.MonadPlus m) => Control.Arrow.ArrowZero (Data.MonadicStreamFunction.Core.MStreamF m)
+ Data.MonadicStreamFunction.Core: MStreamF :: (a -> m (b, MStreamF m a b)) -> MStreamF m a b
+ Data.MonadicStreamFunction.Core: [unMStreamF] :: MStreamF m a b -> a -> m (b, MStreamF m a b)
+ Data.MonadicStreamFunction.Core: data MStreamF m a b
+ Data.MonadicStreamFunction.Core: delay :: Monad m => a -> MStreamF m a a
+ Data.MonadicStreamFunction.Core: embed :: Monad m => MStreamF m a b -> [a] -> m [b]
+ Data.MonadicStreamFunction.Core: feedback :: Monad m => c -> MStreamF m (a, c) (b, c) -> MStreamF m a b
+ Data.MonadicStreamFunction.Core: iPre :: Monad m => a -> MStreamF m a a
+ Data.MonadicStreamFunction.Core: instance GHC.Base.Monad m => Control.Arrow.Arrow (Data.MonadicStreamFunction.Core.MStreamF m)
+ Data.MonadicStreamFunction.Core: instance GHC.Base.Monad m => Control.Category.Category (Data.MonadicStreamFunction.Core.MStreamF m)
+ Data.MonadicStreamFunction.Core: liftMStreamF :: Monad m => (a -> m b) -> MStreamF m a b
+ Data.MonadicStreamFunction.Core: liftMStreamFBase :: (Monad m2, MonadBase m1 m2) => MStreamF m1 a b -> MStreamF m2 a b
+ Data.MonadicStreamFunction.Core: liftMStreamFPurer :: (Monad m2, Monad m1) => (forall c. m1 c -> m2 c) -> MStreamF m1 a b -> MStreamF m2 a b
+ Data.MonadicStreamFunction.Core: liftMStreamFTrans :: (MonadTrans t, Monad m, Monad (t m)) => MStreamF m a b -> MStreamF (t m) a b
+ Data.MonadicStreamFunction.Core: performOnFirstSample :: Monad m => m (MStreamF m a b) -> MStreamF m a b
+ Data.MonadicStreamFunction.Core: reactimate :: Monad m => MStreamF m () () -> m ()
+ Data.MonadicStreamFunction.Core: reactimateB :: Monad m => MStreamF m () Bool -> m ()
+ Data.MonadicStreamFunction.Core: switch :: Monad m => MStreamF m a (b, Maybe c) -> (c -> MStreamF m a b) -> MStreamF m a b
+ Data.MonadicStreamFunction.Instances: elementwise :: Monad m => (b -> c) -> MStreamF m a b -> MStreamF m a c
+ Data.MonadicStreamFunction.Instances: elementwise2 :: Monad m => (b -> c -> d) -> MStreamF m a b -> MStreamF m a c -> MStreamF m a d
+ Data.MonadicStreamFunction.Instances.Num: instance (GHC.Base.Monad m, GHC.Float.Floating b) => GHC.Float.Floating (Data.MonadicStreamFunction.Core.MStreamF m a b)
+ Data.MonadicStreamFunction.Instances.Num: instance (GHC.Base.Monad m, GHC.Num.Num b) => GHC.Num.Num (Data.MonadicStreamFunction.Core.MStreamF m a b)
+ Data.MonadicStreamFunction.Instances.Num: instance (GHC.Base.Monad m, GHC.Real.Fractional b) => GHC.Real.Fractional (Data.MonadicStreamFunction.Core.MStreamF m a b)
+ Data.MonadicStreamFunction.Instances.VectorSpace: instance (GHC.Base.Monad m, Data.VectorSpace.RModule v) => Data.VectorSpace.RModule (Data.MonadicStreamFunction.Core.MStreamF m a v)
+ Data.MonadicStreamFunction.Instances.VectorSpace: instance (GHC.Base.Monad m, Data.VectorSpace.VectorSpace v) => Data.VectorSpace.VectorSpace (Data.MonadicStreamFunction.Core.MStreamF m a v)
+ Data.MonadicStreamFunction.Parallel: (&|&) :: Monad m => MStreamF m a b -> MStreamF m a c -> MStreamF m a (b, c)
+ Data.MonadicStreamFunction.Parallel: (*|*) :: Monad m => MStreamF m a b -> MStreamF m c d -> MStreamF m (a, c) (b, d)
+ Data.VectorSpace: (*^) :: RModule v => Groundring v -> v -> v
+ Data.VectorSpace: (^*) :: RModule v => v -> Groundring v -> v
+ Data.VectorSpace: (^+^) :: RModule v => v -> v -> v
+ Data.VectorSpace: (^-^) :: RModule v => v -> v -> v
+ Data.VectorSpace: (^/) :: VectorSpace v => v -> Groundfield v -> v
+ Data.VectorSpace: class RModule v => InnerProductSpace v
+ Data.VectorSpace: class RModule v => NormedSpace v
+ Data.VectorSpace: class Num (Groundring v) => RModule v where type Groundring v (^*) = flip (*^) (*^) = flip (^*) negateVector v = (- 1) *^ v v1 ^-^ v2 = v1 ^+^ negateVector v2 where {
+ Data.VectorSpace: class (Fractional (Groundring v), RModule v) => VectorSpace v where v ^/ a = (1 / a) *^ v
+ Data.VectorSpace: dot :: InnerProductSpace v => v -> v -> Groundfield v
+ Data.VectorSpace: negateVector :: RModule v => v -> v
+ Data.VectorSpace: norm :: NormedSpace v => v -> Groundfield v
+ Data.VectorSpace: type family Groundring v;
+ Data.VectorSpace: zeroVector :: RModule v => v
+ Data.VectorSpace: }
+ Data.VectorSpace.Instances: instance GHC.Num.Num a => Data.VectorSpace.InnerProductSpace a
+ Data.VectorSpace.Instances: instance GHC.Num.Num a => Data.VectorSpace.RModule a
+ Data.VectorSpace.Instances: instance GHC.Real.Fractional a => Data.VectorSpace.VectorSpace a
+ Data.VectorSpace.Specific: instance Data.VectorSpace.RModule GHC.Integer.Type.Integer
+ Data.VectorSpace.Specific: instance Data.VectorSpace.RModule GHC.Types.Double
+ Data.VectorSpace.Specific: instance Data.VectorSpace.RModule GHC.Types.Float
+ Data.VectorSpace.Specific: instance Data.VectorSpace.RModule GHC.Types.Int
+ Data.VectorSpace.Specific: instance Data.VectorSpace.VectorSpace GHC.Types.Double
+ Data.VectorSpace.Specific: instance Data.VectorSpace.VectorSpace GHC.Types.Float
+ Data.VectorSpace.Tuples: instance (Data.VectorSpace.Groundfield a ~ Data.VectorSpace.Groundfield b, Data.VectorSpace.InnerProductSpace a, Data.VectorSpace.InnerProductSpace b) => Data.VectorSpace.InnerProductSpace (a, b)
+ Data.VectorSpace.Tuples: instance (Data.VectorSpace.Groundfield a ~ Data.VectorSpace.Groundfield b, Data.VectorSpace.VectorSpace a, Data.VectorSpace.VectorSpace b) => Data.VectorSpace.VectorSpace (a, b)
+ Data.VectorSpace.Tuples: instance (Data.VectorSpace.Groundring a ~ Data.VectorSpace.Groundring b, Data.VectorSpace.RModule a, Data.VectorSpace.RModule b) => Data.VectorSpace.RModule (a, b)
+ Data.VectorSpace.Tuples: instance GHC.Num.Num a => Data.VectorSpace.InnerProductSpace (a, a, a)
+ Data.VectorSpace.Tuples: instance GHC.Num.Num a => Data.VectorSpace.InnerProductSpace (a, a, a, a)
+ Data.VectorSpace.Tuples: instance GHC.Num.Num a => Data.VectorSpace.InnerProductSpace (a, a, a, a, a)
+ Data.VectorSpace.Tuples: instance GHC.Num.Num a => Data.VectorSpace.RModule (a, a, a)
+ Data.VectorSpace.Tuples: instance GHC.Num.Num a => Data.VectorSpace.RModule (a, a, a, a)
+ Data.VectorSpace.Tuples: instance GHC.Num.Num a => Data.VectorSpace.RModule (a, a, a, a, a)
+ Data.VectorSpace.Tuples: instance GHC.Real.Fractional a => Data.VectorSpace.VectorSpace (a, a, a)
+ Data.VectorSpace.Tuples: instance GHC.Real.Fractional a => Data.VectorSpace.VectorSpace (a, a, a, a)
+ Data.VectorSpace.Tuples: instance GHC.Real.Fractional a => Data.VectorSpace.VectorSpace (a, a, a, a, a)

Files

LICENSE view
@@ -1,33 +1,30 @@-In the original BSD license, both occurrences of the phrase "COPYRIGHT-HOLDERS AND CONTRIBUTORS" in the disclaimer read "REGENTS AND-CONTRIBUTORS".--Here is the license template:--Copyright (c) 2016, Manuel Bärenz (University of Bamberg), Ivan Perez-(University of Nottingham).+Copyright (c) 2016, Ivan Perez and Manuel Bärenz  All rights reserved.  Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are-met:+modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright-notice, this list of conditions and the following disclaimer.+    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright-notice, this list of conditions and the following disclaimer in the-documentation and/or other materials provided with the distribution.+    * 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. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT-HOLDER 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.+    * Neither the name of Ivan Perez and Manuel Bärenz nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT+OWNER 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.
dunai.cabal view
@@ -1,8 +1,8 @@ name:                dunai-version:             0.0.1.0+version:             0.1.0.0 synopsis:            Generalised reactive framework supporting classic, arrowized and monadic FRP. -- description:-license:             BSD2+license:             BSD3 license-file:        LICENSE author:              Ivan Perez, Manuel Bärenz maintainer:          ivan.perez@keera.co.uk@@ -12,10 +12,72 @@ -- extra-source-files: cabal-version:       >=1.10 +-- You can disable the hlint test suite with -f-test-hlint+flag test-hlint+  default: False+  manual: True++-- You can disable the haddock coverage test suite with -f-test-doc-coverage+flag test-doc-coverage+  default: False+  manual: True+ library-  exposed-modules:   Data.MonadicStreamFunction+  exposed-modules:   Control.Monad.Trans.MStreamF+                     Data.MonadicStreamFunction+                     Data.MonadicStreamFunction.Core+                     Data.MonadicStreamFunction.ArrowChoice+                     Data.MonadicStreamFunction.ArrowLoop+                     Data.MonadicStreamFunction.ArrowPlus+                     Data.MonadicStreamFunction.Instances+                     Data.MonadicStreamFunction.Instances.Num+                     Data.MonadicStreamFunction.Instances.VectorSpace+                     Data.MonadicStreamFunction.Parallel -  build-depends:     base >=4.6 && < 5+		     -- Auxiliary definitions+                     Data.VectorSpace+                     Data.VectorSpace.Instances+                     Data.VectorSpace.Tuples+                     Data.VectorSpace.Specific++  other-modules:     Control.Arrow.Util+                     Data.Tuple.Util++  build-depends:     base >=4.6 && < 5,+                     transformers,+                     transformers-base   hs-source-dirs:    src   default-language:  Haskell2010   ghc-options:       -Wall -fno-warn-unused-do-bind++test-suite hlint+  type: exitcode-stdio-1.0+  main-is: hlint.hs+  hs-source-dirs: tests+  if !flag(test-hlint)+    buildable: False+  else+    build-depends:+      base,+      hlint >= 1.7++-- Verify that the code is thoroughly documented+test-suite haddock-coverage+  type: exitcode-stdio-1.0+  main-is: HaddockCoverage.hs+  ghc-options: -Wall+  hs-source-dirs: tests++  if !flag(test-doc-coverage)+    buildable: False+  else+    build-depends:+      base >= 4 && < 5,+      directory,+      filepath,+      process,+      regex-posix++source-repository head+  type:     git+  location: git@bitbucket.org:iperezdominguez/dunai.git
+ src/Control/Arrow/Util.hs view
@@ -0,0 +1,30 @@+module Control.Arrow.Util where++-- Do we even need that module? How much of it exists in the standard library?++import Control.Arrow+import Control.Category (id)+import Prelude hiding (id)++-- Hah! I shall implement this for TimelessSFs and SFs at the same time!+constantly :: Arrow a => b -> a c b+constantly = arr . const+{-# INLINE constantly #-}++-- More strongly bound arrow combinators+infixr 4 <-<+(<-<) :: Arrow a => a c d -> a b c -> a b d+(<-<) = (<<<)+{-# INLINE (<-<) #-}++infixr 4 >->+(>->) :: Arrow a => a b c -> a c d -> a b d+(>->) = (>>>)+{-# INLINE (>->) #-}+++(&&&!) :: Arrow a => a b c -> a b () -> a b c+a1 &&&! a2 = (a1 &&& a2) >>> arr fst++sink :: Arrow a => a b c -> a c () -> a b c+a1 `sink` a2 = a1 >>> (id &&& a2) >>> arr fst
+ src/Control/Monad/Trans/MStreamF.hs view
@@ -0,0 +1,509 @@+{-# LANGUAGE Arrows              #-}+{-# LANGUAGE Rank2Types          #-}++module Control.Monad.Trans.MStreamF where++import Data.Monoid+import Control.Applicative+import Control.Arrow+import Control.Monad.Trans.Class+import Control.Monad.Trans.Except+import Control.Monad.Trans.List+import Control.Monad.Trans.Maybe+import Control.Monad.Trans.State.Strict+import Control.Monad.Trans.Reader+import Control.Monad.Trans.RWS.Strict hiding (tell, asks, put)+import Control.Monad.Trans.Writer.Strict++import Data.MonadicStreamFunction++-- * Attempt at writing a more generic MSF lifting combinator.  This is+-- here only to make it easier to find, in a perfect world we'd move+-- this to a different module/branch, or at least to the bottom of the+-- file.+--+-- TODO: does this also work well with the state and the writer monads?+--+-- Even if this code works, it's difficult to understand the concept.+--+-- It is also unclear how much it helps. Ideally, the auxiliary function+-- should operate only on monadic values, not monadic stream functions.+-- That way we could separate concepts: namely the recursion pattern+-- from the monadic lifting/unlifting/sequencing.+--+-- Maybe if we split f in several functions, one that does some sort of+-- a -> a1 transformation, another that does some b1 -> b+-- transformation, with the monads and continuations somewhere, it'll+-- make more sense.+--+-- Based on this lifting function we can also defined all the other+-- liftings we have in Core:+--+-- liftMStreamFPurer' :: (Monad m1, Monad m)+--                    => (m1 (b, MStreamF m1 a b) -> m (b, MStreamF m1 a b))+--                    -> MStreamF m1 a b+--                    -> MStreamF m  a b+-- liftMStreamFPurer' f = lifterS (\g a -> f $ g a)+--+-- More liftings:+-- liftMStreamFTrans = liftMStreamFPurer lift+-- liftMStreamFBase  = liftMStreamFPurer liftBase+--+-- And a strict version of liftMStreamFPurer:+-- liftMStreamPurer' f = liftMStreamFPurer (f >=> whnfVal)+--   where whnfVal p@(b,_) = b `seq` return p+--+-- MB: I'm not sure we're gaining much insight by rewriting all the lifting+-- functions like that.+-- IP: I said the same thing above ("It is also unclear how much it+-- helps."). It's work in progress.+--+-- MB: The type (a1 -> m1 (b1, MStreamF m1 a1 b1)) is just MStreamF m1 a1 b1.+-- IP: I'm looking for a lifting pattern in terms of m m1 a b a1 and b1. By+-- exposing the function, I'm hoping to *eventually see* the pattern. If I hide+-- it in the MStreamF, then it'll always remain hidden.+lifterS :: (Monad m, Monad m1)+        => ((a1 -> m1 (b1, MStreamF m1 a1 b1)) -> a -> m (b, MStreamF m1 a1 b1))+        -> MStreamF m1 a1 b1+        -> MStreamF m  a  b+lifterS f msf = MStreamF $ \a -> do+  (b, msf') <- f (unMStreamF msf) a+  return (b, lifterS f msf')++-- ** Another wrapper idea+transS :: (Monad m1, Monad m2)+       => (a2 -> m1 a1)+       -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c))+       -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2+transS transformInput transformOutput msf = MStreamF $ \a2 -> do+    (b2, msf') <- transformOutput a2 $ unMStreamF msf =<< transformInput a2+    return (b2, transS transformInput transformOutput msf')++-- ** A more general lifting mechanism that enables recovery.+transG1 :: (Monad m1, Functor m2, Monad m2)+        => (a2 -> m1 a1)+        -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c))+        -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2+transG1 transformInput transformOutput msf =+  transG transformInput transformOutput' msf+    where+      -- transformOutput' :: forall c. a2 -> m1 (b1, c) -> m2 (b2, Maybe c)+      transformOutput' a b = second Just <$> transformOutput a b++transG :: (Monad m1, Monad m2)+       => (a2 -> m1 a1)+       -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, Maybe c))+       -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2+transG transformInput transformOutput msf = go+  where go = MStreamF $ \a2 -> do+               (b2, msf') <- transformOutput a2 $ unMStreamF msf =<< transformInput a2+               case msf' of+                 Just msf'' -> return (b2, transG transformInput transformOutput msf'')+                 Nothing    -> return (b2, go)++-- transGN :: (Monad m1, Monad m2)+--         => (a2 -> m1 a1)+--         -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, [c]))+--         -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2+-- transGN transformInput transformOutput msf = go+--   where go = MStreamF $ \a2 -> do+--                (b2, msf') <- transformOutput a2 $ unMStreamF msf =<< transformInput a2+--                case msf' of+--                  []      -> return (b2, go)+--                  [msf''] -> return (b2, transGN transformInput transformOutput msf'')+--                  ms      ->++-- ** Alternative Reader wrapping/unwrapping MSF combinators+readerS' :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b+readerS' = lifterS wrapReaderT++runReaderS'' :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b+runReaderS'' = transG transformInput transformOutput+  where+    transformInput  (_, a) = return a+    transformOutput (s, _) m1 = do (r, c) <- runReaderT m1 s+                                   return (r, Just c)+++runStateS''' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)+runStateS''' = transG transformInput transformOutput+  where+    transformInput  (_, a)           = return a+    transformOutput (s, _) msfaction = sym <$> runStateT msfaction s+    sym ((b, msf), s)                = ((s, b), Just msf)++runMaybeS'' :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)+runMaybeS'' = transG transformInput transformOutput+  where+    transformInput       = return+    transformOutput _ m1 = do r <- runMaybeT m1+                              case r of+                                Nothing     -> return (Nothing, Nothing)+                                Just (b, c) -> return (Just b,  Just c)++{-+readerS'' :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b+readerS'' = transS transformInput transformOutput+  where+    transformInput :: a -> m (s, a)+    transformInput a = (,) <$> asks <*> pure a+    transformOutput _ = lift+-}++runReaderS' :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b+runReaderS' = lifterS unwrapReaderT++-- *** Wrapping/unwrapping functions+--+-- IP: Alternative formulation (typechecks just fine):+--+-- FIXME: The foralls may get in the way. They may not be necessary.  MB+-- raised the issue already for similar code in Core.+--+type Wrapper   m1 m2 t1 t2 = forall a b . (t1 a -> m2 b     ) -> (a    -> m1 (t2 b))+type Unwrapper m1 m2 t1 t2 = forall a b . (a    -> m1 (t2 b)) -> (t1 a -> m2 b     )+--+-- Helper type, for when we need some identity * -> * type constructor that+-- does not get in the way.+--+type Id a = a+--+-- And for the Reader, we can now define+type ReaderWrapper   s m = Wrapper   (ReaderT s m) m ((,) s) Id+type ReaderUnwrapper s m = Unwrapper (ReaderT s m) m ((,) s) Id+-- and use the types:+-- wrapReaderT   :: ReaderWrapper s m+-- unwrapReaderT :: ReaderUnwrapper s m++wrapReaderT :: ((s, a) -> m b) -> a -> ReaderT s m b+wrapReaderT g i = ReaderT $ g . flip (,) i++unwrapReaderT :: (a -> ReaderT s m b) -> (s, a) -> m b+unwrapReaderT g i = uncurry (flip runReaderT) $ second g i++-- ** Alternative State wrapping/unwrapping MSF combinators+--+-- IPerez: TODO: Is this exactly the same as stateS?+stateS' :: (Functor m, Monad m) => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b+stateS' = lifterS (\g i -> StateT ((resort <$>) . (g . flip (,) i)))+ where resort ((s, b), ct) = ((b, ct), s)++-- stateS' :: Monad m => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b+-- stateS' = lifterS $ \f a -> StateT $ \s -> do+--   ((s', b), msf') <- f (s, a)+--   return ((b, msf'), s')++runStateS' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)+runStateS' = lifterS (\g i -> resort <$> uncurry (flip runStateT) (second g i))+ where resort ((b, msf), s) = ((s, b), msf)+++runStateS'' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)+runStateS'' = transS transformInput transformOutput+  where+    transformInput  (_, a)           = return a+    transformOutput (s, _) msfaction = sym <$> runStateT msfaction s+    sym ((b, msf), s)                = ((s, b), msf)++{-+stateS'' :: Monad m => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b+stateS'' = transS transformInput transformOutput+  where+    transformInput  (_, a) = return a+    transformOutput (s, _) = do+        put s+-}+-- ** Alternative Writer wrapping/unwrapping MSF combinators+--++writerS' :: (Monad m, Monoid s) => MStreamF m a (s, b) -> MStreamF (WriterT s m) a b+writerS' = lifterS wrapMSFWriterT++runWriterS' :: (Monoid s, Functor m, Monad m) => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)+runWriterS' = lifterS unwrapMSFWriterT++writerS'' :: (Monad m, Monoid w) => MStreamF m a (w, b) -> MStreamF (WriterT w m) a b+writerS'' = transS transformInput transformOutput+  where+    transformInput = return+    transformOutput _ msfaction = do+        ((w, b), msf') <- lift msfaction+        tell w+        return (b, msf')++runWriterS'' :: (Monoid s, Functor m, Monad m) => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)+runWriterS'' = transS transformInput transformOutput+  where+    transformInput              = return+    transformOutput _ msfaction = sym <$> runWriterT msfaction+    sym ((b, msf), s)           = ((s, b), msf)++-- *** Wrapping/unwrapping functions+--+-- TODO: These are *almost*-MSF-agnostic wrapping/unwrapping functions.+-- The continuations (and therefore the stream functions) are still+-- there, but now we know nothing about them, not even their type.+-- Monadic actions carry an extra value, of some polymorphic type ct,+-- which is only necessary to extract the output and the context.+--+-- wrapMSFWriterT :: (Monad m, Functor m) => (a -> WriterT s m (b, ct)) -> a -> m ((s, b), ct)+wrapMSFWriterT :: (Monoid s, Monad m) => (a -> m ((s, b), ct)) -> a -> WriterT s m (b, ct)+wrapMSFWriterT g i = do+  ((s, b), msf) <- lift $ g i+  tell s+  return (b, msf)++unwrapMSFWriterT :: (Monad m, Functor m) => (a -> WriterT s m (b, ct)) -> a -> m ((s, b), ct)+unwrapMSFWriterT g i = resort <$> runWriterT (g i)+  where resort ((b, msf), s) = ((s, b), msf)++-- * Reader monad+readerS :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b+readerS msf = MStreamF $ \a -> do+  (b, msf') <- ReaderT $ \s -> unMStreamF msf (s, a)+  return (b, readerS msf')++runReaderS :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b+runReaderS msf = MStreamF $ \(s,a) -> do+  (b, msf') <- runReaderT (unMStreamF msf a) s+  return (b, runReaderS msf')++-- ** Auxiliary functions related to ReaderT++-- IP: Is runReaderS_ msf s = arr (\a -> (s,a)) >>> runReaderS msf ?+-- MB: Yes, but possibly more efficient.+runReaderS_ :: Monad m => MStreamF (ReaderT s m) a b -> s -> MStreamF m a b+runReaderS_ msf s = MStreamF $ \a -> do+    (b, msf') <- runReaderT (unMStreamF msf a) s+    return (b, runReaderS_ msf' s)++-- * State monad+stateS :: Monad m => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b+stateS msf = MStreamF $ \a -> StateT $ \s -> do+    ((s', b), msf') <- unMStreamF msf (s, a)+    return ((b, stateS msf'), s')++runStateS :: Monad m => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)+runStateS msf = MStreamF $ \(s, a) -> do+    ((b, msf'), s') <- runStateT (unMStreamF msf a) s+    return ((s', b), runStateS msf')++-- ** Auxiliary functions related to StateT++-- IP: Is runStateS_ msf s = feedback s $ runStateS msf >>> arr (\(s,b) -> ((s,b), s)) ?+runStateS_ :: Monad m => MStreamF (StateT s m) a b -> s -> MStreamF m a (s, b)+runStateS_ msf s = MStreamF $ \a -> do+    ((b, msf'), s') <- runStateT (unMStreamF msf a) s+    return ((s', b), runStateS_ msf' s')++-- IP: Is runStateS__ msf s = feedback s $ runStateS msf >>> arr (\(s,b) -> (b, s)) ?+runStateS__ :: Monad m => MStreamF (StateT s m) a b -> s -> MStreamF m a b+runStateS__ msf s = MStreamF $ \a -> do+    ((b, msf'), s') <- runStateT (unMStreamF msf a) s+    return (b, runStateS__ msf' s')++-- * Writer monad+writerS :: (Monad m, Monoid s) => MStreamF m a (s, b) -> MStreamF (WriterT s m) a b+writerS msf = MStreamF $ \a -> do+    ((s, b), msf') <- lift $ unMStreamF msf a+    tell s+    return (b, writerS msf')++runWriterS :: Monad m => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)+runWriterS msf = MStreamF $ \a -> do+    ((b, msf'), s') <- runWriterT $ unMStreamF msf a+    return ((s', b), runWriterS msf')++-- * RWS (Reader-Writer-State) monad++runRWSS :: (Functor m, Monad m, Monoid w)+        => MStreamF (RWST r w s m) a b+        -> MStreamF m (r, s, a) (w, s, b)+runRWSS = transS transformInput transformOutput+  where+    transformInput  (_, _, a) = return a+    transformOutput (r, s, _) msfaction = sym <$> runRWST msfaction r s+    sym ((b, msf'), s, w) = ((w, s, b), msf')+++-- * Maybe monad++exit :: Monad m => MStreamF (MaybeT m) a b+exit = MStreamF $ const $ MaybeT $ return Nothing++exitWhen :: Monad m => (a -> Bool) -> MStreamF (MaybeT m) a a+exitWhen condition = go where+    go = MStreamF $ \a -> MaybeT $+        if condition a+        then return Nothing+        else return $ Just (a, go)++exitIf :: Monad m => MStreamF (MaybeT m) Bool ()+exitIf = MStreamF $ \b -> MaybeT $ return $ if b then Nothing else Just ((), exitIf)++-- Just a is passed along, Nothing causes the whole MStreamF to exit+maybeExit :: Monad m => MStreamF (MaybeT m) (Maybe a) a+maybeExit = MStreamF $ MaybeT . return . fmap (\x -> (x, maybeExit))++mapMaybeS :: Monad m => MStreamF m a b -> MStreamF m (Maybe a) (Maybe b)+mapMaybeS msf = go+  where+    go = MStreamF $ \maybeA -> case maybeA of+                                 Just a -> do+                                     (b, msf') <- unMStreamF msf a+                                     return (Just b, mapMaybeS msf')+                                 Nothing -> return (Nothing, go)++-- mapMaybeS msf == runMaybeS (inMaybeT >>> lift mapMaybeS)++inMaybeT :: Monad m => MStreamF (MaybeT m) (Maybe a) a+inMaybeT = liftMStreamF $ MaybeT . return++{-+maybeS :: Monad m => MStreamF m a (Maybe b) -> MStreamF (MaybeT m) a b+maybeS msf = MStreamF $ \a -> MaybeT $ return $ unMStreamF msf a+-- maybeS msf == lift msf >>> inMaybeT+-}++runMaybeS :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)+runMaybeS msf = go+  where+    go = MStreamF $ \a -> do+           bmsf <- runMaybeT $ unMStreamF msf a+           case bmsf of+             Just (b, msf') -> return (Just b, runMaybeS msf')+             Nothing        -> return (Nothing, go)++{-+-- MB: Doesn't typecheck, I don't know why+--+-- IP: Because of the forall in runTS.+--+-- From the action runMaybeT msfaction it does not know that+-- the second element of the pair in 'thing' will be a continuation.+--+-- The first branch of the case works because you are passing the+-- msf' as is.+--+-- In the second one, you are passing msf, which has the specific type+-- MStreamF (MaybeT m) a b.+--+-- Two things you can try (to help you see that this is indeed why GHC is+-- complaining):+--   - Make the second continuation undefined. Then it typechecks.+--   - Use ScopedTypeVariables and a let binding to type msf' in the+--   first branch of the case selector. It'll complain about the type+--   of msf' if you say it's forcibly a MStreamF (MaybeT m) a b.+--++runMaybeS'' :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)+runMaybeS'' msf = transS transformInput transformOutput msf+  where+    transformInput  = return+    transformOutput _ msfaction = do+      thing <- runMaybeT msfaction+      case thing of+        Just (b, msf') -> return (Just b, msf')+        Nothing        -> return (Nothing, msf)+-}++untilMaybe :: Monad m => MStreamF m a b -> MStreamF m b Bool -> MStreamF (MaybeT m) a b+untilMaybe msf cond = proc a -> do+    b <- liftMStreamFTrans msf -< a+    c <- liftMStreamFTrans cond -< b+    inMaybeT -< if c then Nothing else Just b++catchMaybe :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a b -> MStreamF m a b+catchMaybe msf1 msf2 = MStreamF $ \a -> do+    cont <- runMaybeT $ unMStreamF msf1 a+    case cont of+        Just (b, msf1') -> return (b, msf1' `catchMaybe` msf2)+        Nothing         -> unMStreamF msf2 a+++-- * Exception monad++{-+catchS' :: Monad m => MStreamF (ExceptT e m) a b -> (e -> m (b, MStreamF m a b)) -> MStreamF m a b+catchS' msf f = MStreamF $ \a -> (unMStreamF msf a) f `catchFinal` f+-}+catchS :: Monad m => MStreamF (ExceptT e m) a b -> (e -> MStreamF m a b) -> MStreamF m a b+catchS msf f = MStreamF $ \a -> do+    cont <- runExceptT $ unMStreamF msf a+    case cont of+        Left e          -> unMStreamF (f e) a+        Right (b, msf') -> return (b, msf' `catchS` f)++exceptS :: Monad m => MStreamF (ExceptT e m) a b -> MStreamF m a (Either e b)+exceptS msf = go+ where+   go = MStreamF $ \a -> do+          cont <- runExceptT $ unMStreamF msf a+          case cont of+            Left e          -> return (Left e,  go)+            Right (b, msf') -> return (Right b, exceptS msf')++-- catchFinal :: Monad m => ExceptT e m a -> (e -> m a) -> m a+-- catchFinal action f = do+--     ea <- runExceptT action+--     case ea of+--         Left  e -> f e+--         Right a -> return a+++throwOnCond :: Monad m => (a -> Bool) -> e -> MStreamF (ExceptT e m) a a+throwOnCond cond e = proc a -> if cond a+    then liftMStreamF throwE -< e+    else returnA -< a++throwOnCondM :: Monad m => (a -> m Bool) -> e -> MStreamF (ExceptT e m) a a+throwOnCondM cond e = proc a -> do+    b <- liftMStreamF (lift . cond) -< a+    if b+    then liftMStreamF throwE -< e+    else returnA -< a+++throwOn :: Monad m => e -> MStreamF (ExceptT e m) Bool ()+throwOn e = proc b -> throwOn' -< (b, e)++throwOn' :: Monad m => MStreamF (ExceptT e m) (Bool, e) ()+throwOn' = proc (b, e) -> if b+    then liftMStreamF throwE -< e+    else returnA -< ()++-- Similar to delayed switching. Looses a b in case of exception+untilE :: Monad m => MStreamF m a b -> MStreamF m b (Maybe e)+       -> MStreamF (ExceptT e m) a b+untilE msf msfe = proc a -> do+    b <- liftMStreamFTrans msf -< a+    me <- liftMStreamFTrans msfe -< b+    inExceptT -< (ExceptT . return) (maybe (Right b) Left me)++throwMaybe :: Monad m => MStreamF (ExceptT e m) (Maybe e) (Maybe a)+throwMaybe = mapMaybeS $ liftMStreamF throwE++throwS :: Monad m => MStreamF (ExceptT e m) e a+throwS = liftMStreamF throwE++inExceptT :: Monad m => MStreamF (ExceptT e m) (ExceptT e m a) a+inExceptT = liftMStreamF id -- extracts value from monadic action++-- * List monad++-- Name alternative (in the article): collect+widthFirst :: (Functor m, Monad m) => MStreamF (ListT m) a b -> MStreamF m a [b]+widthFirst msf = widthFirst' [msf] where+    widthFirst' msfs = MStreamF $ \a -> do+        (bs, msfs') <- unzip . concat <$> mapM (runListT . flip unMStreamF a) msfs+        return (bs, widthFirst' msfs')+++-- Name alternatives: "choose", "parallely" (problematic because it's not multicore)+sequenceS :: Monad m => [MStreamF m a b] -> MStreamF (ListT m) a b+sequenceS msfs = MStreamF $ \a -> ListT $ sequence $ apply a <$> msfs+  where+    apply a msf = do+        (b, msf') <- unMStreamF msf a+        return (b, sequenceS [msf'])+-- sequenceS = foldl (<+>) arrowzero . map liftMStreamFTrans
src/Data/MonadicStreamFunction.hs view
@@ -1,1 +1,168 @@-module Data.MonadicStreamFunction where+-- | Monadic Stream Functions are synchronized stream functions+-- with side effects.+module Data.MonadicStreamFunction+  ( module Control.Arrow+  , module Data.MonadicStreamFunction+  , module X+  )+ where++-- External+import Control.Applicative+import Control.Arrow+import Control.Category (Category(..))+import Control.Monad+import Control.Monad.Base+import Data.Monoid+import Prelude hiding ((.), id, sum)++-- Internal (generic)+import Data.VectorSpace+import Data.VectorSpace.Instances()++import Data.MonadicStreamFunction.Core        as X+import Data.MonadicStreamFunction.ArrowChoice as X+import Data.MonadicStreamFunction.ArrowLoop   as X+import Data.MonadicStreamFunction.ArrowPlus   as X++-- ** Instances for monadic streams++instance Functor m => Functor (MStreamF m r)+  where+    -- fmap f as = as >>> arr f+    fmap f as = MStreamF $ \r -> fTuple <$> unMStreamF as r+      where+        fTuple (a, as') = (f a, f <$> as')++instance Applicative m => Applicative (MStreamF m r) where+  -- pure a = constantly a+  pure a = MStreamF $ \_ -> pure (a, pure a)+  {-+  fs <*> as = proc _ -> do+      f <- fs -< ()+      a <- as -< ()+      returnA -< f a+  -}+  fs <*> as = MStreamF $ \r -> applyTuple <$> unMStreamF fs r <*> unMStreamF as r+    where+      applyTuple (f, fs') (a, as') = (f a, fs' <*> as')++-- ** Lifts++{-# DEPRECATED insert "Don't use this. liftMStreamF id instead" #-}+insert :: Monad m => MStreamF m (m a) a+insert = liftMStreamF id+-- This expands to the old code:+--+-- MStreamF $ \ma -> do+--   a <- ma+--   return (a, insert)++liftMStreamF_ :: Monad m => m b -> MStreamF m a b+liftMStreamF_ = liftMStreamF . const++-- * Monadic lifting from one monad into another++-- ** Monad stacks++(^>>>) :: MonadBase m1 m2 => MStreamF m1 a b -> MStreamF m2 b c -> MStreamF m2 a c+sf1 ^>>> sf2 = (liftMStreamFBase sf1) >>> sf2+{-# INLINE (^>>>) #-}++(>>>^) :: MonadBase m1 m2 => MStreamF m2 a b -> MStreamF m1 b c -> MStreamF m2 a c+sf1 >>>^ sf2 = sf1 >>> (liftMStreamFBase sf2)+{-# INLINE (>>>^) #-}++-- ** Delays and signal overwriting++-- See also: 'iPre'++iPost :: Monad m => b -> MStreamF m a b -> MStreamF m a b+iPost b sf = MStreamF $ \_ -> return (b, sf)++next :: Monad m => b -> MStreamF m a b -> MStreamF m a b+next b sf = MStreamF $ \a -> do+  (b', sf') <- unMStreamF sf a+  return (b, next b' sf')+-- rather, once delay is tested:+-- next b sf = sf >>> delay b++-- ** Switching++-- See also: 'switch', and the exception monad combinators for MSFs in+-- Control.Monad.Trans.MStreamF++untilS :: Monad m => MStreamF m a b -> MStreamF m b Bool -> MStreamF m a (b, Maybe ())+untilS sf1 sf2 = sf1 >>> (arr id &&& (sf2 >>> arr boolToMaybe))+  where boolToMaybe x = if x then Just () else Nothing++andThen :: Monad m => MStreamF m a (b, Maybe ()) -> MStreamF m a b -> MStreamF m a b+andThen sf1 sf2 = switch sf1 $ const sf2++-- ** Feedback loops++-- | Missing: 'feedback'++-- * Adding side effects+withSideEffect :: Monad m => (a -> m b) -> MStreamF m a a+withSideEffect method = (id &&& liftMStreamF method) >>> arr fst++withSideEffect_ :: Monad m => m b -> MStreamF m a a+withSideEffect_ method = withSideEffect $ const method++-- * Debugging++traceGeneral :: (Monad m, Show a) => (String -> m ()) -> String -> MStreamF m a a+traceGeneral method msg =+  withSideEffect (method . (msg ++) . show)++trace :: Show a => String -> MStreamF IO a a+trace = traceGeneral putStrLn++-- FIXME: This does not seem to be a very good name.  It should be+-- something like traceWith. It also does too much.+pauseOnGeneral :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MStreamF m a a+pauseOnGeneral cond method msg = withSideEffect $ \a ->+  when (cond a) $ method $ msg ++ show a++pauseOn :: Show a => (a -> Bool) -> String -> MStreamF IO a a+pauseOn cond = pauseOnGeneral cond $ \s -> print s >> getLine >> return ()++-- * Tests and examples++sum :: (Monoid n, Monad m) => MStreamF m n n+sum = sumFrom mempty+{-# INLINE sum #-}++sumFrom :: (Monoid n, Monad m) => n -> MStreamF m n n+sumFrom n0 = MStreamF $ \n -> let acc = n0 `mappend` n+                              -- in acc `seq` return (acc, sumFrom acc)+                              in return (acc, sumFrom acc)+-- sum = feedback 0 (arr (uncurry (+) >>> dup))+--  where dup x = (x,x)++count :: (Num n, Monad m) => MStreamF m () n+count = arr (const (Sum 1)) >>> sum >>> arr getSum++unfold :: Monad m => (a -> (b,a)) -> a -> MStreamF m () b+unfold f a = MStreamF $ \_ -> let (b,a') = f a in b `seq` return (b, unfold f a')+-- unfold f x = feedback x (arr (snd >>> f))++repeatedly :: Monad m => (a -> a) -> a -> MStreamF m () a+repeatedly f = repeatedly'+ where repeatedly' a = MStreamF $ \() -> let a' = f a in a' `seq` return (a, repeatedly' a')+-- repeatedly f x = feedback x (arr (f >>> \x -> (x,x)))++-- FIXME: This should *not* be in this module+mapMStreamF :: Monad m => MStreamF m a b -> MStreamF m [a] [b]+mapMStreamF sf = MStreamF $ consume sf+  where+    consume :: Monad m => MStreamF m a t -> [a] -> m ([t], MStreamF m [a] [t])+    consume sf []     = return ([], mapMStreamF sf)+    consume sf (a:as) = do+      (b, sf')   <- unMStreamF sf a+      (bs, sf'') <- consume sf' as+      b `seq` return (b:bs, sf'')++-- * Streams (or generators)+type MStream m a = MStreamF m () a
+ src/Data/MonadicStreamFunction/ArrowChoice.hs view
@@ -0,0 +1,12 @@+module Data.MonadicStreamFunction.ArrowChoice where++import Control.Arrow++import Data.MonadicStreamFunction.Core++instance Monad m => ArrowChoice (MStreamF m) where+  left sf = MStreamF f+    where+      f (Left a) = do (b, sf') <- unMStreamF sf a+                      return (Left b, left sf')+      f (Right c) = return (Right c, left sf)
+ src/Data/MonadicStreamFunction/ArrowLoop.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE RecursiveDo #-}+module Data.MonadicStreamFunction.ArrowLoop where++import Data.MonadicStreamFunction.Core++-- External+import Control.Arrow+import Control.Category (Category(..))+import Control.Monad+import Control.Monad.Fix++instance (Monad m, MonadFix m) => ArrowLoop (MStreamF m) where+  -- loop :: a (b, d) (c, d) -> a b c+  loop sf = MStreamF $ \a -> do+              rec ((b,c), sf') <- unMStreamF sf (a, c)+              return (b, loop sf')
+ src/Data/MonadicStreamFunction/ArrowPlus.hs view
@@ -0,0 +1,12 @@+module Data.MonadicStreamFunction.ArrowPlus where++import Control.Arrow+import Control.Monad++import Data.MonadicStreamFunction.Core++instance (Monad m, MonadPlus m) => ArrowZero (MStreamF m) where+  zeroArrow = MStreamF $ const mzero++instance (Monad m, MonadPlus m) => ArrowPlus (MStreamF m) where+  sf1 <+> sf2 = MStreamF $ \a -> unMStreamF sf1 a `mplus` unMStreamF sf2 a
+ src/Data/MonadicStreamFunction/Core.hs view
@@ -0,0 +1,173 @@+{-# LANGUAGE ExplicitForAll #-}+{-# LANGUAGE Rank2Types     #-}+-- | Monadic Stream Functions are synchronized stream functions+-- with side effects.++-- This module contains the core. Only the core. It should be possible+-- to define every function and type outside this module, except for the+-- instances for ArrowLoop, ArrowChoice, etc., without access to the+-- internal constructor for MStreamF and the function 'unMStreamF'.+--+-- It's very hard to know what IS essential to framework and if we start+-- adding all the functions and instances that *may* be useful in one+-- module.+--+-- By separating some instances and functions in other modules , we can+-- easily understand what is the essential idea and then analyse how it+-- is affected by an extension. It also helps demonstrate that something+-- works for MSFs + ArrowChoice, or MSFs + ArrowLoop, etc.+--+-- To address potential violations of basic design principles (like 'not+-- having orphan instances'), the main module Data.MonadicStreamFunction+-- exports everything. Users should *never* import this module+-- individually, but the main module instead.+module Data.MonadicStreamFunction.Core where++-- External+import Control.Applicative+import Control.Arrow+import Control.Category (Category(..))+import Control.Monad+import Control.Monad.Base+import Control.Monad.Trans.Class+import Prelude hiding ((.), id, sum)++-- MStreamF: Stepwise, side-effectful MStreamFs without implicit knowledge of time+data MStreamF m a b = MStreamF { unMStreamF :: a -> m (b, MStreamF m a b) }++instance Monad m => Category (MStreamF m) where+  id = go+    where go = MStreamF $ \a -> return (a, go)+  sf2 . sf1 = MStreamF $ \a -> do+    (b, sf1') <- unMStreamF sf1 a+    (c, sf2') <- unMStreamF sf2 b+    let sf' = sf2' . sf1'+    c `seq` return (c, sf')++instance Monad m => Arrow (MStreamF m) where++  arr f = go+    where go = MStreamF $ \a -> return (f a, go)++  first sf = MStreamF $ \(a,c) -> do+    (b, sf') <- unMStreamF sf a+    b `seq` return ((b, c), first sf')+    -- This is called the "monadic strength" of m++-- ** Lifts+liftMStreamF :: Monad m => (a -> m b) -> MStreamF m a b+liftMStreamF f = go+ where go = MStreamF $ \a -> do+              b <- f a+              return (b, go)++-- * Monadic lifting from one monad into another++-- ** Purer monads++-- IPerez: There is an alternative signature for liftMStreamPurer that also+-- works, and makes the code simpler:+--+-- liftMStreamFPurer :: Monad m => (m1 (b, MStreamF m1 a b) -> m (b, MStreamF m1 a b)) -> MStreamF m1 a b -> MStreamF m a b+--+-- Then we can express:+--+-- liftMStreamFTrans = liftMStreamFPurer lift+-- liftMStreamFBase  = liftMStreamFPurer liftBase+--+-- We could also define a strict version of liftMStreamFPurer as follows:+--+-- liftMStreamPurer' f = liftMStreamFPurer (f >=> whnfVal)+--   where whnfVal p@(b,_) = b `seq` return p+--+-- and leave liftMStreamFPurer as a lazy version (by default).++-- | Lifting purer monadic actions (in an arbitrary way)+liftMStreamFPurer :: (Monad m2, Monad m1) => (forall c . m1 c -> m2 c) -> MStreamF m1 a b -> MStreamF m2 a b+liftMStreamFPurer liftPurer sf = MStreamF $ \a -> do+  (b, sf') <- liftPurer $ unMStreamF sf a+  b `seq` return (b, liftMStreamFPurer liftPurer sf')++-- ** Monad stacks++-- | Lifting inner monadic actions in monad stacks+-- TODO Should be able to express this in terms of MonadBase+liftMStreamFTrans :: (MonadTrans t, Monad m, Monad (t m)) => MStreamF m a b -> MStreamF (t m) a b+liftMStreamFTrans sf = MStreamF $ \a -> do+  (b, sf') <- lift $ unMStreamF sf a+  return (b, liftMStreamFTrans sf')++-- | Lifting the innest monadic actions in a monad stacks (generalisation of liftIO)+liftMStreamFBase :: (Monad m2, MonadBase m1 m2) => MStreamF m1 a b -> MStreamF m2 a b+liftMStreamFBase sf = MStreamF $ \a -> do+  (b, sf') <- liftBase $ unMStreamF sf a+  b `seq` return (b, liftMStreamFBase sf')++-- * MSFs within monadic actions++-- | Extract MSF from a monadic action+performOnFirstSample :: Monad m => m (MStreamF m a b) -> MStreamF m a b+performOnFirstSample sfaction = MStreamF $ \a -> do+  sf <- sfaction+  unMStreamF sf a++-- ** Delays and signal overwriting++iPre :: Monad m => a -> MStreamF m a a+iPre firsta = MStreamF $ \a -> return (firsta, delay a)+-- iPre firsta = feedback firsta $ lift swap+--   where swap (a,b) = (b, a)+-- iPre firsta = next firsta identity++-- FIXME: Remove delay from this module. We should try to make this module+-- small, keeping only primitives.+delay :: Monad m => a -> MStreamF m a a+delay = iPre++-- ** Switching++switch :: Monad m => MStreamF m a (b, Maybe c) -> (c -> MStreamF m a b) -> MStreamF m a b+switch sf f = MStreamF $ \a -> do+  ((b, c), sf') <- unMStreamF sf a+  return (b, maybe (switch sf' f) f c)++-- ** Feedback loops++feedback :: Monad m => c -> MStreamF m (a, c) (b, c) -> MStreamF m a b+feedback c sf = MStreamF $ \a -> do+  ((b', c'), sf') <- unMStreamF sf (a, c)+  return (b', feedback c' sf')++-- * Reactimating++-- | Apply a monadic stream function to a list.+--+-- Because the result is in a monad, it may be necessary to+-- traverse the whole list to evaluate the value in the results to WHNF.+-- For example, if the monad is the maybe monad, this may not produce anything+-- if the MSF produces Nothing at any point, so the output stream cannot+-- consumed progressively.+--+-- To explore the output progressively, use liftMStreamF and (>>>), together+-- with some action that consumes/actuates on the output.+--+-- This is called "runSF" in Liu, Cheng, Hudak, "Causal Commutative Arrows and+-- Their Optimization"+embed :: Monad m => MStreamF m a b -> [a] -> m [b]+embed _  []     = return []+embed sf (a:as) = do+  (b, sf') <- unMStreamF sf a+  bs       <- embed sf' as+  return (b:bs)++-- | Runs an MSF indefinitely passing a unit-carrying input stream.+reactimate :: Monad m => MStreamF m () () -> m ()+reactimate sf = do+  (_, sf') <- unMStreamF sf ()+  reactimate sf'++-- | Runs an MSF indefinitely passing a unit-carrying input stream.+reactimateB :: Monad m => MStreamF m () Bool -> m ()+reactimateB sf = do+  (b, sf') <- unMStreamF sf ()+  if b then return () else reactimateB sf'
+ src/Data/MonadicStreamFunction/Instances.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE TypeFamilies           #-}+module Data.MonadicStreamFunction.Instances where++-- External+import Control.Arrow++-- Internal+import Control.Arrow.Util+import Data.MonadicStreamFunction.Core++-- Numerical operations are defined elementwise on the output+elementwise :: Monad m => (b -> c) -> MStreamF m a b -> MStreamF m a c+elementwise f msf = msf >>> arr f++elementwise2 :: Monad m => (b -> c -> d) -> MStreamF m a b -> MStreamF m a c -> MStreamF m a d+elementwise2 op msf1 msf2 = msf1 &&& msf2 >>> arr (uncurry op)
+ src/Data/MonadicStreamFunction/Instances/Num.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE TypeFamilies           #-}+module Data.MonadicStreamFunction.Instances.Num where+++import Control.Arrow.Util+import Data.MonadicStreamFunction.Core+import Data.MonadicStreamFunction.Instances++instance (Monad m, Num b) => Num (MStreamF m a b) where+    (+)         = elementwise2 (+)+    (-)         = elementwise2 (-)+    (*)         = elementwise2 (*)+    abs         = elementwise abs+    signum      = elementwise signum+    negate      = elementwise negate+    fromInteger = constantly . fromInteger++instance (Monad m, Fractional b) => Fractional (MStreamF m a b) where+    fromRational = constantly . fromRational+    (/)          = elementwise2 (/)+    recip        = elementwise recip++instance (Monad m, Floating b) => Floating (MStreamF m a b) where+    pi      = constantly   pi+    exp     = elementwise  exp+    log     = elementwise  log+    sqrt    = elementwise  sqrt+    (**)    = elementwise2 (**)+    logBase = elementwise2 logBase+    sin     = elementwise  sin+    cos     = elementwise  cos+    tan     = elementwise  tan+    asin    = elementwise  asin+    acos    = elementwise  acos+    atan    = elementwise  atan+    sinh    = elementwise  sinh+    cosh    = elementwise  cosh+    tanh    = elementwise  tanh+    asinh   = elementwise  asinh+    acosh   = elementwise  acosh+    atanh   = elementwise  atanh
+ src/Data/MonadicStreamFunction/Instances/VectorSpace.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE TypeFamilies           #-}+module Data.MonadicStreamFunction.Instances.VectorSpace where+++import Control.Arrow.Util+import Data.MonadicStreamFunction.Core+import Data.MonadicStreamFunction.Instances+import Data.VectorSpace+++-- These conflict with Data.VectorSpace.Instances+instance (Monad m, RModule v) => RModule (MStreamF m a v) where+    type Groundring (MStreamF m a v) = Groundring v+    zeroVector   = constantly zeroVector+    r *^ msf     = elementwise (r *^) msf+    negateVector = elementwise negateVector+    (^+^)        = elementwise2 (^+^)+    (^-^)        = elementwise2 (^-^)++instance (Monad m, VectorSpace v) => VectorSpace (MStreamF m a v) where+    msf ^/ r = elementwise (^/ r) msf
+ src/Data/MonadicStreamFunction/Parallel.hs view
@@ -0,0 +1,27 @@+module Data.MonadicStreamFunction.Parallel where++-- External+import Control.Arrow+-- import Control.Parallel+import GHC.Conc++-- Internal+import Data.MonadicStreamFunction++-- IPerez: This should be similar to the following:+-- (msf1 *** msf2) >>> parS+-- where parS             = arr parTuple+--       parTuple p@(a,b) = (a `par` b `pseq` p)+-- Manuel: but we added strictness annotations to first+-- and so (***) might be strict in both arguments and not take+-- full advantage of parallelism.+--+(*|*) :: Monad m => MStreamF m a b -> MStreamF m c d -> MStreamF m (a, c) (b, d)+msf1 *|* msf2 = MStreamF $ \(a, c) -> do+    (b, msf1') <- unMStreamF msf1 a+    (d, msf2') <- unMStreamF msf2 c+    b `par` d `pseq` return ((b, d), msf1' *|* msf2')+++(&|&) :: Monad m => MStreamF m a b -> MStreamF m a c -> MStreamF m a (b, c)+msf1 &|& msf2 = arr (\a -> (a, a)) >>> (msf1 *|* msf2)
+ src/Data/Tuple/Util.hs view
@@ -0,0 +1,7 @@+module Data.Tuple.Util where++assocR :: ((a, b), c) -> (a, (b, c))+assocR ((a, b), c) = (a, (b, c))++assocL :: (a, (b, c)) -> ((a, b), c)+assocL (a, (b, c)) = ((a, b), c)
+ src/Data/VectorSpace.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE FlexibleContexts       #-}+{-# LANGUAGE UndecidableInstances   #-}+-- |+-- Module      :  Data.VectorSpace+-- Copyright   :  (c) Ivan Perez and Manuel Bärenz+-- License     :  See the LICENSE file in the distribution.+--+-- Maintainer  :  ivan.perez@keera.co.uk+-- Stability   :  provisional+-- Portability :  non-portable (GHC extensions)+--+-- Vector space type relation and basic instances.++module Data.VectorSpace where++------------------------------------------------------------------------------+-- Vector space type relation+------------------------------------------------------------------------------++infixr 6 *^+infixl 6 ^/+infix 6 `dot`+infixl 5 ^+^, ^-^++-- TODO Add laws this should satisfy++class Num (Groundring v) => RModule v where+    type Groundring v+    zeroVector   :: v+    (*^)         :: Groundring v -> v -> v+    (^*)         :: v -> Groundring v -> v+    (^*) = flip (*^)+    (*^) = flip (^*)++    negateVector :: v -> v+    negateVector v = (-1) *^ v++    (^+^)        :: v -> v -> v++    (^-^)        :: v -> v -> v+    v1 ^-^ v2     = v1 ^+^ negateVector v2+++-- Maybe norm and normalize should not be class methods, in which case+-- the constraint on the coefficient space (a) should (or, at least, could)+-- be Fractional (roughly a Field) rather than Floating.++-- Minimal instance: zeroVector, (*^), (^+^), dot+-- class Fractional (Groundfield v) => VectorSpace v where+class (Fractional (Groundring v), RModule v) => VectorSpace v where+    (^/)         :: v -> Groundfield v -> v+    v ^/ a = (1/a) *^ v++type family Groundfield v :: *+type instance Groundfield v = Groundring v++class RModule v => InnerProductSpace v where+    dot          :: v -> v -> Groundfield v++class RModule v => NormedSpace v  where+    norm         :: v -> Groundfield v++{-+instance (Floating (Groundfield v), VectorSpace v, InnerProductSpace v) => NormedSpace v where+    norm v = sqrt (v `dot` v)+-}+{- I'd like to know why this won't work+normalize :: (Eq a, NormedSpace v a) => v -> v+normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector"+    where nv = norm v+    -}
+ src/Data/VectorSpace/Instances.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE UndecidableInstances   #-}+module Data.VectorSpace.Instances where++import Data.VectorSpace+++instance Num a => RModule a where+    type Groundring a = a+    zeroVector     = 0+    a *^ x         = a * x+    negateVector x = -x+    x1 ^+^ x2      = x1 + x2+    x1 ^-^ x2      = x1 - x2+++instance Fractional a => VectorSpace a where+    a ^/ x = a / x++instance Num a => InnerProductSpace a where+    x1 `dot` x2 = x1 * x2
+ src/Data/VectorSpace/Specific.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE TypeFamilies           #-}+module Data.VectorSpace.Specific where++import Data.VectorSpace+++instance RModule Int where+    type Groundring Int = Int+    (^+^) = (+)+    (^*) = (*)+    zeroVector = 0++instance RModule Integer where+    type Groundring Integer = Integer+    (^+^) = (+)+    (^*) = (*)+    zeroVector = 0+++instance RModule Double where+    type Groundring Double = Double+    (^+^) = (+)+    (^*) = (*)+    zeroVector = 0++instance RModule Float where+    type Groundring Float = Float+    (^+^) = (+)+    (^*) = (*)+    zeroVector = 0++instance VectorSpace Double where++instance VectorSpace Float where
+ src/Data/VectorSpace/Tuples.hs view
@@ -0,0 +1,89 @@+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE TypeFamilies           #-}+module Data.VectorSpace.Tuples where++import Data.VectorSpace++------------------------------------------------------------------------------+-- Vector space instances for small tuples of Fractional+------------------------------------------------------------------------------++++instance (Groundring a ~ Groundring b, RModule a, RModule b) => RModule (a, b) where+    type Groundring (a, b) = Groundring a+    zeroVector = (zeroVector, zeroVector)+    (a, b) ^* x = (a ^* x, b ^* x)+    (a1, b1) ^+^ (a2, b2) = (a1 ^+^ a2, b1 ^+^ b2)++instance (Groundfield a ~ Groundfield b, VectorSpace a, VectorSpace b) => VectorSpace (a, b) where+    (a, b) ^/ x = (a ^/ x, b ^/ x)++instance (Groundfield a ~ Groundfield b, InnerProductSpace a, InnerProductSpace b) => InnerProductSpace (a, b) where+    (a1, b1) `dot` (a2, b2) = (a1 `dot` a2) + (b1 `dot` b2)++{-+instance Num a => RModule (a,a) where+    type Groundring (a,a) = a+    zeroVector = (0,0)+    a *^ (x,y) = (a * x, a * y)+    negateVector (x,y) = (-x, -y)+    (x1,y1) ^+^ (x2,y2) = (x1 + x2, y1 + y2)+    (x1,y1) ^-^ (x2,y2) = (x1 - x2, y1 - y2)++instance Fractional a => VectorSpace (a,a) where+    (x,y) ^/ a = (x / a, y / a)+++instance Fractional a => InnerProductSpace (a,a) where+    (x1,y1) `dot` (x2,y2) = x1 * x2 + y1 * y2++-}++instance Num a => RModule (a,a,a) where+    type Groundring (a,a,a) = a+    zeroVector = (0,0,0)+    a *^ (x,y,z) = (a * x, a * y, a * z)+    negateVector (x,y,z) = (-x, -y, -z)+    (x1,y1,z1) ^+^ (x2,y2,z2) = (x1+x2, y1+y2, z1+z2)+    (x1,y1,z1) ^-^ (x2,y2,z2) = (x1-x2, y1-y2, z1-z2)++instance Fractional a => VectorSpace (a,a,a) where+    (x,y,z) ^/ a = (x / a, y / a, z / a)+++instance Num a => InnerProductSpace (a,a,a) where+    (x1,y1,z1) `dot` (x2,y2,z2) = x1 * x2 + y1 * y2 + z1 * z2+++instance Num a => RModule (a,a,a,a) where+    type Groundring (a,a,a,a) = a+    zeroVector = (0,0,0,0)+    a *^ (x,y,z,u) = (a * x, a * y, a * z, a * u)+    negateVector (x,y,z,u) = (-x, -y, -z, -u)+    (x1,y1,z1,u1) ^+^ (x2,y2,z2,u2) = (x1+x2, y1+y2, z1+z2, u1+u2)+    (x1,y1,z1,u1) ^-^ (x2,y2,z2,u2) = (x1-x2, y1-y2, z1-z2, u1-u2)++instance Fractional a => VectorSpace (a,a,a,a) where+    (x,y,z,u) ^/ a = (x / a, y / a, z / a, u / a)+++instance Num a => InnerProductSpace (a,a,a,a) where+    (x1,y1,z1,u1) `dot` (x2,y2,z2,u2) = x1 * x2 + y1 * y2 + z1 * z2 + u1 * u2+++instance Num a => RModule (a,a,a,a,a) where+    type Groundring (a,a,a,a,a) = a+    zeroVector = (0,0,0,0,0)+    a *^ (x,y,z,u,v) = (a * x, a * y, a * z, a * u, a * v)+    negateVector (x,y,z,u,v) = (-x, -y, -z, -u, -v)+    (x1,y1,z1,u1,v1) ^+^ (x2,y2,z2,u2,v2) = (x1+x2, y1+y2, z1+z2, u1+u2, v1+v2)+    (x1,y1,z1,u1,v1) ^-^ (x2,y2,z2,u2,v2) = (x1-x2, y1-y2, z1-z2, u1-u2, v1-v2)++instance Fractional a => VectorSpace (a,a,a,a,a) where+    (x,y,z,u,v) ^/ a = (x / a, y / a, z / a, u / a, v / a)+++instance Num a => InnerProductSpace (a,a,a,a,a) where+    (x1,y1,z1,u1,v1) `dot` (x2,y2,z2,u2,v2) =+        x1 * x2 + y1 * y2 + z1 * z2 + u1 * u2 + v1 * v2
+ tests/HaddockCoverage.hs view
@@ -0,0 +1,91 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Main (HaddockCoverage)+-- Copyright   :  (C) 2015 Ivan Perez+-- License     :  BSD-style (see the file LICENSE)+-- Maintainer  :  Ivan Perez <ivan.perez@keera.co.uk>+-- Stability   :  provisional+-- Portability :  portable+--+-- Copyright notice: This file borrows code+-- https://hackage.haskell.org/package/lens-4.7/src/tests/doctests.hsc+-- which is itself licensed BSD-style as well.+--+-- Run haddock on a source tree and report if anything in any+-- module is not documented.+-----------------------------------------------------------------------------+module Main where++import Control.Applicative+import Control.Monad+import Data.List+import System.Directory+import System.Exit+import System.FilePath+import System.IO+import System.Process+import Text.Regex.Posix++main :: IO ()+main = do+  -- Find haskell modules+  -- TODO: Ideally cabal should do this (provide us with the+  -- list of modules). An alternative would be to use cabal haddock+  -- but that would need a --no-html argument or something like that.+  -- Alternatively, we could use cabal haddock with additional arguments.+  --+  -- See:+  -- https://github.com/keera-studios/haddock/commit/d5d752943c4e5c6c9ffcdde4dc136fcee967c495+  -- https://github.com/haskell/haddock/issues/309#issuecomment-150811929+  files <- getSources++  let haddockArgs = [ "--no-warnings", "--ignore-all-exports" ] ++ files+  let cabalArgs   = [ "exec", "--", "haddock" ] ++ haddockArgs+  (code, out, _err) <- readProcessWithExitCode "cabal" cabalArgs ""++  -- Filter out coverage lines, and find those that denote undocumented+  -- modules.+  --+  -- TODO: is there a way to annotate a function as self-documenting,+  -- in the same way we do with ANN for hlint?+  let isIncompleteModule :: String -> Bool+      isIncompleteModule line = isCoverageLine line && not (line =~ "^ *100%")+        where isCoverageLine :: String -> Bool+              isCoverageLine line = line =~ "^ *[0-9]+%"++  let incompleteModules :: [String]+      incompleteModules = filter isIncompleteModule $ lines out++  -- Based on the result of haddock, report errors and exit.+  -- Note that, unline haddock, this script does not+  -- output anything to stdout. It uses stderr instead+  -- (as it should).+  case (code, incompleteModules) of+    (ExitSuccess  , []) -> return ()+    -- (ExitFailure _, _)  -> exitFailure+    (_            , _)  -> do+      hPutStrLn stderr "The following modules are not fully documented:"+      mapM_ (hPutStrLn stderr) incompleteModules+      exitFailure++getSources :: IO [FilePath]+getSources = filter isHaskellFile <$> go "src"+  where+    go dir = do+      (dirs, files) <- getFilesAndDirectories dir+      (files ++) . concat <$> mapM go dirs++    isHaskellFile fp = (isSuffixOf ".hs" fp || isSuffixOf ".lhs" fp)+                     && not (any (`isSuffixOf` fp) excludedFiles)++    excludedFiles = [ ]++getFilesAndDirectories :: FilePath -> IO ([FilePath], [FilePath])+getFilesAndDirectories dir = do+  c <- map (dir </>) . filter (`notElem` ["..", "."]) <$> getDirectoryContents dir+  (,) <$> filterM doesDirectoryExist c <*> filterM doesFileExist c++-- find-based implementation (not portable)+--+-- getSources :: IO [FilePath]+-- getSources = fmap lines $ readProcess "find" ["src/", "-iname", "*hs"] ""
+ tests/hlint.hs view
@@ -0,0 +1,23 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Main (hlint)+-- Copyright   :  (C) 2013 Edward Kmett+-- License     :  BSD-style (see the file LICENSE)+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- This module runs HLint on the lens source tree.+-----------------------------------------------------------------------------+module Main where++import Control.Monad+import Language.Haskell.HLint+import System.Environment+import System.Exit++main :: IO ()+main = do+    args <- getArgs+    hints <- hlint $ ["src", "--cross", "--hint=tests/HLint.hs" ] ++ args+    unless (null hints) exitFailure