dunai 0.8.1 → 0.8.2
raw patch · 24 files changed
+558/−300 lines, 24 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Monad.Trans.MSF.Except: dSwitch :: Monad m => MSF m a (b, Maybe c) -> (c -> MSF m a b) -> MSF m a b
Files
- CHANGELOG +73/−0
- dunai.cabal +163/−84
- src/Control/Arrow/Util.hs +6/−1
- src/Control/Monad/Trans/MSF.hs +6/−2
- src/Control/Monad/Trans/MSF/Except.hs +36/−13
- src/Control/Monad/Trans/MSF/List.hs +6/−4
- src/Control/Monad/Trans/MSF/Maybe.hs +12/−9
- src/Control/Monad/Trans/MSF/RWS.hs +12/−8
- src/Control/Monad/Trans/MSF/Random.hs +12/−9
- src/Control/Monad/Trans/MSF/Reader.hs +8/−5
- src/Control/Monad/Trans/MSF/State.hs +9/−4
- src/Control/Monad/Trans/MSF/Writer.hs +8/−4
- src/Data/MonadicStreamFunction.hs +33/−32
- src/Data/MonadicStreamFunction/Async.hs +53/−50
- src/Data/MonadicStreamFunction/Core.hs +32/−27
- src/Data/MonadicStreamFunction/Instances/ArrowChoice.hs +8/−3
- src/Data/MonadicStreamFunction/Instances/ArrowLoop.hs +13/−8
- src/Data/MonadicStreamFunction/Instances/ArrowPlus.hs +9/−4
- src/Data/MonadicStreamFunction/Instances/Num.hs +9/−6
- src/Data/MonadicStreamFunction/Instances/VectorSpace.hs +10/−3
- src/Data/MonadicStreamFunction/InternalCore.hs +19/−15
- src/Data/MonadicStreamFunction/Parallel.hs +6/−1
- src/Data/MonadicStreamFunction/ReactHandle.hs +6/−3
- src/Data/MonadicStreamFunction/Util.hs +9/−5
+ CHANGELOG view
@@ -0,0 +1,73 @@+2022-04-21 Ivan Perez <ivan.perez@keera.co.uk>+ * dunai.cabal: Version bump (0.8.2) (#280), syntax rules (#271),+ declare CHANGELOG (#273), declare subdir of source-repository (#272).+ * src/: Fix haddock syntax error in documentation of switch (#274),+ introduce new dSwitch function (#275), syntax rules (#277), remove+ unused module Ultrametric (#278), remove unused module+ CausalCommutative (#279).++2021-10-21 Ivan Perez <ivan.perez@keera.co.uk>+ * src:/: Code cleaning.+ * dunai.cabal: Version bump (0.8.1).+ * README.md: update example to new API, fix broken link, update badge,+ fix typo.+ * Thanks: @DireWolf707.++2021-09-06 Ivan Perez <ivan.perez@keera.co.uk>+ * src:/: Code cleaning.+ * dunai.cabal: Version bump (0.8.0).+ * README.md: support for GHC 8.10.+ * Thanks: @walseb, @turion, @bgluzman, @mezzomondo.++2020-04-18 Ivan Perez <ivan.perez@keera.co.uk>+ * src:/: Add new utilities. Fix behaviour of listToMaybeS.+ * dunai.cabal: Version bump (0.7.0).+ * README.md: support for GHC 8.8.+ * Cleaning and hlinting changes.+ * Thanks: @turion, @Linearity.++2020-01-25 Ivan Perez <ivan.perez@keera.co.uk>+ * src:/: Remove Data.VectorSpace.+ * src:/: Fix error in documentation of embed.+ * dunai.cabal: use simple-affine-space. Version bump (0.6.0).+ * README.md: support for GHC 8.6. Add links to videos. Fix typos.+ * Thanks: @chriz-keera, @turion, @Rizary, @dynomite567,+ @alexmarginean16.++2019-09-29 Ivan Perez <ivan.perez@keera.co.uk>+ * src:/: Fixes error in List on older versions of GHC.+ * dunai.cabal: exposes List support. Version bump (0.5.2.1).++2019-09-29 Ivan Perez <ivan.perez@keera.co.uk>+ * src:/: Fixes error in List support implementation.+ * dunai.cabal: exposes List support. Version bump (0.5.2).++2018-11-03 Ivan Perez <ivan.perez@keera.co.uk>+ * src:/: Fixes failed patterns in do notation.+ * dunai.cabal: Version bump (0.5.1).+ * Thanks: @turion, @ggreif.++2018-11-03 Ivan Perez <ivan.perez@keera.co.uk>+ * src:/ Renames lifting functions, moves definitions around.+ * dunai.cabal: Version bump (0.5).+ * Thanks: @turion.++2017-12-05 Ivan Perez <ivan.perez@keera.co.uk>+ * Adds support for random numbers using MonadRandom+ (thanks Jonathan Thaler -- @thalerjonathan).+ * Removes MSF constructor from many definitions+ (by Manuel Bärenz -- @turion).+ * Adds support for older GHC versions.+ * Moves some definitions/modules around.+ * dunai.cabal: Version bump (0.4).+ * examples/: Changes licenses, updates examples to use new API.++2017-10-31 Ivan Perez <ivan.perez@keera.co.uk>+ * src/: Re-structure modules, completes documentation.+ * stack.yaml: New stack configuration.+ * Fixes compilation errors with older versions of GHC.+ * dunai.cabal: Version bump (0.3), adds repo URL, documentation.+ * examples/: Updates examples to use new API.++Copyright (c) 2016, Ivan Perez and Manuel Bärenz.+All rights reserved.
dunai.cabal view
@@ -1,14 +1,53 @@-name: dunai-version: 0.8.1-synopsis: Generalised reactive framework supporting classic, arrowized and monadic FRP.-homepage: https://github.com/ivanperez-keera/dunai+-- 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:+--+-- * Redistributions of source code must retain the above copyright+-- notice, this list of conditions and the following disclaimer.+--+-- * 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.+--+-- * 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.+cabal-version: >= 1.10+build-type: Simple++name: dunai+version: 0.8.2+author: Ivan Perez, Manuel Bärenz+maintainer: ivan.perez@keera.co.uk+homepage: https://github.com/ivanperez-keera/dunai+license: BSD3+license-file: LICENSE+copyright: Copyright (c) 2016 - Ivan Perez and Manuel Bärenz+category: Reactivity, FRP+synopsis:+ Generalised reactive framework supporting classic, arrowized and monadic FRP. description: Dunai is a DSL for strongly-typed CPS-based composable transformations. . Dunai is based on a concept of Monadic Stream Functions (MSFs). MSFs are- transformations defined by a function @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@- that executes one step of a simulation, and produces an output in a monadic- context, and a continuation to be used for future steps.+ transformations defined by a function+ @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@ that executes one step of a+ simulation, and produces an output in a monadic context, and a continuation+ to be used for future steps. . MSFs are a generalisation of the implementation mechanism used by Yampa, Wormholes and other FRP and reactive implementations.@@ -25,115 +64,155 @@ with @ListT@ gives rise to parallelism with broadcasting. . MSFs can be used to implement many FRP variants, including Arrowized FRP,- Classic FRP, and plain reactive programming. Arrowized and applicative- syntax are both supported.+ Classic FRP, and plain reactive programming. Arrowized and applicative syntax+ are both supported. . For a very detailed introduction to MSFs, see: <http://dl.acm.org/citation.cfm?id=2976010> (mirror: <http://www.cs.nott.ac.uk/~psxip1/#FRPRefactored>).-license: BSD3-license-file: LICENSE-author: Ivan Perez, Manuel Bärenz-maintainer: ivan.perez@keera.co.uk--- copyright:-category: Reactivity, FRP-build-type: Simple--- extra-source-files:-cabal-version: >=1.10 ++extra-source-files:+ CHANGELOG+++source-repository head+ type: git+ location: git@github.com:ivanperez-keera/dunai.git+ subdir: dunai++ -- You can disable the hlint test suite with -f-test-hlint flag test-hlint description: Enable hlint test suite- default: False- manual: True+ default: False+ manual: True -- You can disable the haddock coverage test suite with -f-test-doc-coverage flag test-doc-coverage description: Enable haddock coverage test suite- default: False- manual: True+ default: False+ manual: True + library- exposed-modules: Control.Monad.Trans.MSF- Control.Monad.Trans.MSF.Except- Control.Monad.Trans.MSF.Maybe- Control.Monad.Trans.MSF.List- Control.Monad.Trans.MSF.Random- Control.Monad.Trans.MSF.Reader- Control.Monad.Trans.MSF.RWS- Control.Monad.Trans.MSF.State- Control.Monad.Trans.MSF.Writer- Data.MonadicStreamFunction- Data.MonadicStreamFunction.Core- Data.MonadicStreamFunction.Async- Data.MonadicStreamFunction.Instances.ArrowChoice- Data.MonadicStreamFunction.Instances.ArrowLoop- Data.MonadicStreamFunction.Instances.ArrowPlus- Data.MonadicStreamFunction.Instances.Num- Data.MonadicStreamFunction.Instances.VectorSpace- Data.MonadicStreamFunction.InternalCore- Data.MonadicStreamFunction.Parallel- Data.MonadicStreamFunction.ReactHandle- Data.MonadicStreamFunction.Util+ exposed-modules:+ Control.Monad.Trans.MSF+ Control.Monad.Trans.MSF.Except+ Control.Monad.Trans.MSF.List+ Control.Monad.Trans.MSF.Maybe+ Control.Monad.Trans.MSF.Random+ Control.Monad.Trans.MSF.Reader+ Control.Monad.Trans.MSF.RWS+ Control.Monad.Trans.MSF.State+ Control.Monad.Trans.MSF.Writer+ Data.MonadicStreamFunction+ Data.MonadicStreamFunction.Async+ Data.MonadicStreamFunction.Core+ Data.MonadicStreamFunction.Instances.ArrowChoice+ Data.MonadicStreamFunction.Instances.ArrowLoop+ Data.MonadicStreamFunction.Instances.ArrowPlus+ Data.MonadicStreamFunction.Instances.Num+ Data.MonadicStreamFunction.Instances.VectorSpace+ Data.MonadicStreamFunction.InternalCore+ Data.MonadicStreamFunction.Parallel+ Data.MonadicStreamFunction.ReactHandle+ Data.MonadicStreamFunction.Util - other-modules: Control.Arrow.Util+ other-modules:+ Control.Arrow.Util - build-depends: base >=4.6 && < 5,- transformers,- transformers-base,- MonadRandom,- simple-affine-space+ build-depends:+ base >= 4.6 && < 5+ , MonadRandom+ , simple-affine-space+ , transformers+ , transformers-base - hs-source-dirs: src- default-language: Haskell2010- ghc-options: -Wall -fno-warn-unused-do-bind+ default-language:+ Haskell2010 + hs-source-dirs:+ src++ ghc-options:+ -Wall -fno-warn-unused-do-bind+ if impl(ghc <= 7.8.4)- build-depends: transformers-compat+ build-depends:+ transformers-compat + test-suite hlint- type: exitcode-stdio-1.0- main-is: HLintMain.hs- hs-source-dirs: tests- default-language: Haskell2010+ type:+ exitcode-stdio-1.0++ main-is:+ HLintMain.hs++ default-language:+ Haskell2010++ hs-source-dirs:+ tests+ if !flag(test-hlint)- buildable: False+ buildable:+ False else build-depends:- base,- hlint >= 1.7+ 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- default-language: Haskell2010+ type:+ exitcode-stdio-1.0 + main-is:+ HaddockCoverage.hs++ default-language:+ Haskell2010++ hs-source-dirs:+ tests++ ghc-options:+ -Wall+ if !flag(test-doc-coverage)- buildable: False+ buildable:+ False else build-depends:- base >= 4 && < 5,- directory,- filepath,- process,- regex-posix+ base >= 4 && < 5+ , directory+ , filepath+ , process+ , regex-posix -source-repository head- type: git- location: git@github.com:ivanperez-keera/dunai.git test-suite regression-tests- type: exitcode-stdio-1.0- main-is: RegressionTests.hs- ghc-options: -Wall- hs-source-dirs: tests- default-language: Haskell2010+ type:+ exitcode-stdio-1.0++ main-is:+ RegressionTests.hs++ default-language:+ Haskell2010++ hs-source-dirs:+ tests++ ghc-options:+ -Wall+ build-depends:- base >=4 && <5,- transformers,- dunai,- tasty,- tasty-hunit+ base >= 4 && <5+ , transformers+ , tasty+ , tasty-hunit++ , dunai
src/Control/Arrow/Util.hs view
@@ -1,4 +1,9 @@--- | Utility functions to work with 'Arrow's.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk+--+-- Utility functions to work with 'Arrow's. module Control.Arrow.Util where import Control.Arrow
src/Control/Monad/Trans/MSF.hs view
@@ -1,6 +1,10 @@ {-# LANGUAGE Rank2Types #-}---- | This module reexports nearly all submodules. RWS is not exported since+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk+--+-- This module reexports nearly all submodules. RWS is not exported since -- names collide with Reader, State and Writer. module Control.Monad.Trans.MSF ( module Control.Monad.Trans.MSF.Except
src/Control/Monad/Trans/MSF/Except.hs view
@@ -1,24 +1,28 @@-{-# LANGUAGE Arrows #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE Rank2Types #-}-{-# LANGUAGE TupleSections #-}--- | 'MSF's in the 'ExceptT' monad are monadic stream functions--- that can throw exceptions,--- i.e. return an exception value instead of a continuation.--- This module gives ways to throw exceptions in various ways,--- and to handle them through a monadic interface.+{-# LANGUAGE Arrows #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE TupleSections #-}+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk+--+-- 'MSF's in the 'ExceptT' monad are monadic stream functions that can throw+-- exceptions, i.e. return an exception value instead of a continuation. This+-- module gives ways to throw exceptions in various ways, and to handle them+-- through a monadic interface. module Control.Monad.Trans.MSF.Except ( module Control.Monad.Trans.MSF.Except , module Control.Monad.Trans.Except ) where -- External- import Control.Applicative import qualified Control.Category as Category-import Control.Monad (liftM, ap)+import Control.Monad (ap, liftM) import Control.Monad.Trans.Class-import Control.Monad.Trans.Except hiding (liftCallCC, liftListen, liftPass) -- Avoid conflicting exports+import Control.Monad.Trans.Except hiding (liftCallCC, liftListen,+ liftPass) import Control.Monad.Trans.Maybe -- Internal@@ -177,6 +181,8 @@ return = pure MSFExcept msf >>= f = MSFExcept $ handleExceptT msf $ runMSFExcept . f +-- | Execute an MSF and, if it throws an exception, recover by switing to a+-- second MSF. handleExceptT :: Monad m => MSF (ExceptT e1 m) a b@@ -265,7 +271,11 @@ reactimateB :: Monad m => MSF m () Bool -> m () reactimateB sf = reactimateExcept $ try $ liftTransS sf >>> throwOn () --- * Analog to Yampa's switch, with Maybe instead of Event+-- | Run first MSF until the second value in the output tuple is @Just c@ (for+-- some @c@), then start the second MSF.+--+-- Analog to Yampa's [@switch@](https://hackage.haskell.org/package/Yampa/docs/FRP-Yampa-Switches.html#v:switch),+-- with 'Maybe' instead of @Event@. switch :: Monad m => MSF m a (b, Maybe c) -> (c -> MSF m a b) -> MSF m a b switch sf f = catchS ef f where@@ -273,6 +283,18 @@ (b,me) <- liftTransS sf -< a inExceptT -< ExceptT $ return $ maybe (Right b) Left me +-- | Run first MSF until the second value in the output tuple is @Just c@ (for+-- some @c@), then start the second MSF.+--+-- Analog to Yampa's [@dswitch@](https://hackage.haskell.org/package/Yampa/docs/FRP-Yampa-Switches.html#v:dSwitch),+-- with 'Maybe' instead of @Event@.+dSwitch :: Monad m => MSF m a (b, Maybe c) -> (c -> MSF m a b) -> MSF m a b+dSwitch sf f = catchS ef f+ where+ ef = feedback Nothing $ proc (a, me) -> do+ throwMaybe -< me+ liftTransS sf -< a+ -- | More general lifting combinator that enables recovery. Note that, unlike a -- polymorphic lifting function @forall a . m a -> m1 a@, this auxiliary -- function needs to be a bit more structured, and produces a Maybe value. The@@ -289,6 +311,7 @@ Just msf'' -> return (b2, transG transformInput transformOutput msf'') Nothing -> return (b2, go) +-- | Use a generic handler to handle exceptions in MSF processing actions. handleGen :: (a -> m1 (b1, MSF m1 a b1) -> m2 (b2, MSF m2 a b2)) -> MSF m1 a b1 -> MSF m2 a b2
src/Control/Monad/Trans/MSF/List.hs view
@@ -1,17 +1,20 @@ {-# LANGUAGE CPP #-}+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk module Control.Monad.Trans.MSF.List ( module Control.Monad.Trans.MSF.List , module Control.Monad.Trans.List ) where -- External-import Control.Monad.Trans.List- hiding (liftCallCC, liftCatch) -- Avoid conflicting exports- #if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<$>)) #endif +import Control.Monad.Trans.List hiding (liftCallCC, liftCatch)+ -- Internal import Data.MonadicStreamFunction import Data.MonadicStreamFunction.InternalCore (MSF (MSF, unMSF))@@ -45,4 +48,3 @@ (b, sf') <- unMSF sf a (bs, sf'') <- consume sf' as b `seq` return (b:bs, sf'')-
src/Control/Monad/Trans/MSF/Maybe.hs view
@@ -1,10 +1,13 @@-{-# LANGUAGE Arrows #-}-{-# LANGUAGE Rank2Types #-}-{- |-The 'Maybe' monad is very versatile. It can stand for default arguments,-for absent values, and for (nondescript) exceptions.-The latter viewpoint is most natural in the context of 'MSF's.--}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE Rank2Types #-}+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk+--+-- The 'Maybe' monad is very versatile. It can stand for default arguments,+-- for absent values, and for (nondescript) exceptions. The latter viewpoint+-- is most natural in the context of 'MSF's. module Control.Monad.Trans.MSF.Maybe ( module Control.Monad.Trans.MSF.Maybe , module Control.Monad.Trans.Maybe@@ -12,8 +15,8 @@ ) where -- External-import Control.Monad.Trans.Maybe- hiding (liftCallCC, liftCatch, liftListen, liftPass) -- Avoid conflicting exports+import Control.Monad.Trans.Maybe hiding (liftCallCC, liftCatch, liftListen,+ liftPass) -- Internal import Control.Monad.Trans.MSF.Except
src/Control/Monad/Trans/MSF/RWS.hs view
@@ -1,20 +1,24 @@--- | This module combines the wrapping and running functions--- for the 'Reader', 'Writer' and 'State' monad layers in a single layer.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk --+-- This module combines the wrapping and running functions for the 'Reader',+-- 'Writer' and 'State' monad layers in a single layer.+-- -- It is based on the _strict_ 'RWS' monad 'Control.Monad.Trans.RWS.Strict',--- so when combining it with other modules such as @mtl@'s,--- the strict version has to be included, i.e. 'Control.Monad.RWS.Strict'--- instead of 'Control.Monad.RWS' or 'Control.Monad.RWS.Lazy'.+-- so when combining it with other modules such as @mtl@'s, the strict version+-- has to be included, i.e. 'Control.Monad.RWS.Strict' instead of+-- 'Control.Monad.RWS' or 'Control.Monad.RWS.Lazy'. module Control.Monad.Trans.MSF.RWS ( module Control.Monad.Trans.MSF.RWS , module Control.Monad.Trans.RWS.Strict ) where -- External-import Control.Monad.Trans.RWS.Strict- hiding (liftCallCC, liftCatch) -- Avoid conflicting exports+import Control.Monad.Trans.RWS.Strict hiding (liftCallCC, liftCatch)+import Data.Functor ((<$>)) import Data.Monoid-import Data.Functor ((<$>)) -- Internal import Data.MonadicStreamFunction
src/Control/Monad/Trans/MSF/Random.hs view
@@ -1,12 +1,15 @@--- | In this module, 'MSF's in a monad supporting random number generation--- (i.e. having the 'RandT' layer in its stack) can be run.--- Running means supplying an initial random number generator,--- where the update of the generator at every random number generation--- is already taken care of.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk ----- Under the hood, 'RandT' is basically just 'StateT',--- with the current random number generator as mutable state.-+-- In this module, 'MSF's in a monad supporting random number generation (i.e.+-- having the 'RandT' layer in its stack) can be run. Running means supplying+-- an initial random number generator, where the update of the generator at+-- every random number generation is already taken care of.+--+-- Under the hood, 'RandT' is basically just 'StateT', with the current random+-- number generator as mutable state. module Control.Monad.Trans.MSF.Random ( runRandS@@ -24,8 +27,8 @@ import Control.Monad.Random -- Internal-import Data.MonadicStreamFunction import Control.Monad.Trans.MSF.State+import Data.MonadicStreamFunction -- | Run an 'MSF' in the 'RandT' random number monad transformer -- by supplying an initial random generator.
src/Control/Monad/Trans/MSF/Reader.hs view
@@ -1,7 +1,11 @@-{-# LANGUAGE Rank2Types #-}---- | 'MSF's with a 'Reader' monadic layer.+{-# LANGUAGE Rank2Types #-}+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk --+-- 'MSF's with a 'Reader' monadic layer.+-- -- This module contains functions to work with 'MSF's that include a 'Reader' -- monadic layer. This includes functions to create new 'MSF's that include an -- additional layer, and functions to flatten that layer out of the 'MSF`'s@@ -15,8 +19,7 @@ ) where -- External-import Control.Monad.Trans.Reader- hiding (liftCallCC, liftCatch) -- Avoid conflicting exports+import Control.Monad.Trans.Reader hiding (liftCallCC, liftCatch) -- Internal import Data.MonadicStreamFunction
src/Control/Monad/Trans/MSF/State.hs view
@@ -1,6 +1,11 @@ {-# LANGUAGE Rank2Types #-}--- | 'MSF's with a 'State' monadic layer.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk --+-- 'MSF's with a 'State' monadic layer.+-- -- This module contains functions to work with 'MSF's that include a 'State' -- monadic layer. This includes functions to create new 'MSF's that include an -- additional layer, and functions to flatten that layer out of the 'MSF`'s@@ -21,9 +26,9 @@ -- External import Control.Applicative-import Control.Monad.Trans.State.Strict- hiding (liftCallCC, liftCatch, liftListen, liftPass) -- Avoid conflicting exports-import Data.Tuple (swap)+import Control.Monad.Trans.State.Strict hiding (liftCallCC, liftCatch,+ liftListen, liftPass)+import Data.Tuple (swap) -- Internal import Data.MonadicStreamFunction.Core
src/Control/Monad/Trans/MSF/Writer.hs view
@@ -1,5 +1,10 @@--- | 'MSF's with a 'Writer' monadic layer.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk --+-- 'MSF's with a 'Writer' monadic layer.+-- -- This module contains functions to work with 'MSF's that include a 'Writer' -- monadic layer. This includes functions to create new 'MSF's that include an -- additional layer, and functions to flatten that layer out of the 'MSF`'s@@ -17,9 +22,8 @@ ) where -- External-import Control.Monad.Trans.Writer.Strict- hiding (liftCallCC, liftCatch, pass) -- Avoid conflicting exports-import Data.Functor ((<$>))+import Control.Monad.Trans.Writer.Strict hiding (liftCallCC, liftCatch, pass)+import Data.Functor ((<$>)) import Data.Monoid -- Internal
src/Data/MonadicStreamFunction.hs view
@@ -1,41 +1,45 @@--- | Monadic Stream Functions are synchronized stream functions--- with side effects.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk ----- 'MSF's are defined by a function--- @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@--- that executes one step of a simulation, and produces an output in a--- monadic context, and a continuation to be used for future steps.+-- Monadic Stream Functions are synchronized stream functions with side+-- effects. ----- See the module "Data.MonadicStreamFunction.Core" for details.+-- 'MSF's are defined by a function+-- @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@+-- that executes one step of a simulation, and produces an output in a monadic+-- context, and a continuation to be used for future steps. ----- 'MSF's are a generalisation of the implementation mechanism used by Yampa,--- Wormholes and other FRP and reactive implementations.+-- See the module "Data.MonadicStreamFunction.Core" for details. ----- When combined with different monads, they produce interesting effects. For--- example, when combined with the 'Maybe' monad, they become transformations--- that may stop producing outputs (and continuations). The 'Either' monad--- gives rise to 'MSF's that end with a result (akin to Tasks in Yampa, and--- Monadic FRP).+-- 'MSF's are a generalisation of the implementation mechanism used by Yampa,+-- Wormholes and other FRP and reactive implementations. ----- Flattening, that is, going from some structure @MSF (t m) a b@ to @MSF m a b@--- for a specific transformer @t@ often gives rise to known FRP constructs.--- For instance, flattening with 'EitherT' gives rise to switching, and--- flattening with 'ListT' gives rise to parallelism with broadcasting.+-- When combined with different monads, they produce interesting effects. For+-- example, when combined with the 'Maybe' monad, they become transformations+-- that may stop producing outputs (and continuations). The 'Either' monad+-- gives rise to 'MSF's that end with a result (akin to Tasks in Yampa, and+-- Monadic FRP). ----- 'MSF's can be used to implement many FRP variants, including Arrowized FRP,--- Classic FRP, and plain reactive programming. Arrowized and applicative--- syntax are both supported.+-- Flattening, that is, going from some structure @MSF (t m) a b@ to @MSF m a+-- b@ for a specific transformer @t@ often gives rise to known FRP constructs.+-- For instance, flattening with 'EitherT' gives rise to switching, and+-- flattening with 'ListT' gives rise to parallelism with broadcasting. ----- For a very detailed introduction to 'MSF's, see:--- <http://dl.acm.org/citation.cfm?id=2976010>--- (mirror: <http://www.cs.nott.ac.uk/~psxip1/#FRPRefactored>).+-- 'MSF's can be used to implement many FRP variants, including Arrowized FRP,+-- Classic FRP, and plain reactive programming. Arrowized and applicative+-- syntax are both supported. ----- Apart from the modules exported, this module exports instances from:+-- For a very detailed introduction to 'MSF's, see:+-- <http://dl.acm.org/citation.cfm?id=2976010>+-- (mirror: <http://www.cs.nott.ac.uk/~psxip1/#FRPRefactored>). ----- - "Data.MonadicStreamFunction.Instances.ArrowChoice"--- - "Data.MonadicStreamFunction.Instances.ArrowLoop"--- - "Data.MonadicStreamFunction.Instances.ArrowPlus"-+-- Apart from the modules exported, this module exports instances from:+--+-- - "Data.MonadicStreamFunction.Instances.ArrowChoice"+-- - "Data.MonadicStreamFunction.Instances.ArrowLoop"+-- - "Data.MonadicStreamFunction.Instances.ArrowPlus" module Data.MonadicStreamFunction ( module Control.Arrow , module Data.MonadicStreamFunction.Core@@ -44,16 +48,13 @@ where -- External- import Control.Arrow -- Internal- import Data.MonadicStreamFunction.Core import Data.MonadicStreamFunction.Util -- Internal (Instances)- import Data.MonadicStreamFunction.Instances.ArrowChoice () import Data.MonadicStreamFunction.Instances.ArrowLoop () import Data.MonadicStreamFunction.Instances.ArrowPlus ()
src/Data/MonadicStreamFunction/Async.hs view
@@ -1,59 +1,62 @@--- | This module contains operations on monadic streams that are asynchronous,--- i.e. that change the speed at which data enters or leaves the 'MSF'.-+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk+--+-- This module contains operations on monadic streams that are asynchronous,+-- i.e. that change the speed at which data enters or leaves the 'MSF'. module Data.MonadicStreamFunction.Async where -- Internal import Data.MonadicStreamFunction.Core import Data.MonadicStreamFunction.InternalCore-import Data.MonadicStreamFunction.Util (MStream)--{- |-Concatenates a monadic stream of lists to a monadic stream.-The stream of lists will be called exactly when new data is needed.--Example:-->>> let intstream = constS $ putStrLn "Enter a list of Ints:" >> readLn :: MStream IO [Int]->>> reactimate $ concatS intstream >>> arrM print-Enter a list of Ints:-[1,2,33]-1-2-33-Enter a list of Ints:-[]-Enter a list of Ints:-[]-Enter a list of Ints:-[1,2]-1-2-Enter a list of Ints:-...--Beware that @concatS msf@ becomes unproductive when @msf@ starts outputting empty lists forever.-This is ok:-->>> let boolToList b = if b then ["Yes"] else []->>> let everyOddEmpty = count >>> arr (even >>> boolToList)->>> reactimate $ concatS everyOddEmpty >>> arrM print-"Yes"-"Yes"-"Yes"-"Yes"-"Yes"-...--But this will be caught in a loop:+import Data.MonadicStreamFunction.Util (MStream) ->>> let after3Empty = count >>> arr ((<= 3) >>> boolToList)->>> reactimate $ concatS after3Empty >>> arrM print-"Yes"-"Yes"-"Yes"-^CInterrupted.--}+-- |+-- Concatenates a monadic stream of lists to a monadic stream.+-- The stream of lists will be called exactly when new data is needed.+--+-- Example:+--+-- >>> let intstream = constS $ putStrLn "Enter a list of Ints:" >> readLn :: MStream IO [Int]+-- >>> reactimate $ concatS intstream >>> arrM print+-- Enter a list of Ints:+-- [1,2,33]+-- 1+-- 2+-- 33+-- Enter a list of Ints:+-- []+-- Enter a list of Ints:+-- []+-- Enter a list of Ints:+-- [1,2]+-- 1+-- 2+-- Enter a list of Ints:+-- ...+--+-- Beware that @concatS msf@ becomes unproductive when @msf@ starts outputting empty lists forever.+-- This is ok:+--+-- >>> let boolToList b = if b then ["Yes"] else []+-- >>> let everyOddEmpty = count >>> arr (even >>> boolToList)+-- >>> reactimate $ concatS everyOddEmpty >>> arrM print+-- "Yes"+-- "Yes"+-- "Yes"+-- "Yes"+-- "Yes"+-- ...+--+-- But this will be caught in a loop:+--+-- >>> let after3Empty = count >>> arr ((<= 3) >>> boolToList)+-- >>> reactimate $ concatS after3Empty >>> arrM print+-- "Yes"+-- "Yes"+-- "Yes"+-- ^CInterrupted. concatS :: Monad m => MStream m [b] -> MStream m b concatS msf = MSF $ \_ -> tick msf [] where
src/Data/MonadicStreamFunction/Core.hs view
@@ -1,33 +1,38 @@ {-# LANGUAGE Rank2Types #-}--- | Monadic Stream Functions are synchronized stream functions--- with side effects.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk ----- 'MSF's are defined by a function--- @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@--- that executes one step of a simulation, and produces an output in a--- monadic context, and a continuation to be used for future steps.+-- Monadic Stream Functions are synchronized stream functions with side+-- effects. ----- 'MSF's are a generalisation of the implementation mechanism used by Yampa,--- Wormholes and other FRP and reactive implementations.+-- 'MSF's are defined by a function+-- @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@+-- that executes one step of a simulation, and produces an output in a monadic+-- context, and a continuation to be used for future steps. ----- When combined with different monads, they produce interesting effects. For--- example, when combined with the 'Maybe' monad, they become transformations--- that may stop producing outputs (and continuations). The 'Either' monad--- gives rise to 'MSF's that end with a result (akin to Tasks in Yampa, and--- Monadic FRP).+-- 'MSF's are a generalisation of the implementation mechanism used by Yampa,+-- Wormholes and other FRP and reactive implementations. ----- Flattening, that is, going from some structure @MSF (t m) a b@ to @MSF m a b@--- for a specific transformer @t@ often gives rise to known FRP constructs.--- For instance, flattening with 'EitherT' gives rise to switching, and--- flattening with 'ListT' gives rise to parallelism with broadcasting.+-- When combined with different monads, they produce interesting effects. For+-- example, when combined with the 'Maybe' monad, they become transformations+-- that may stop producing outputs (and continuations). The 'Either' monad+-- gives rise to 'MSF's that end with a result (akin to Tasks in Yampa, and+-- Monadic FRP). ----- 'MSF's can be used to implement many FRP variants, including Arrowized FRP,--- Classic FRP, and plain reactive programming. Arrowized and applicative--- syntax are both supported.+-- Flattening, that is, going from some structure @MSF (t m) a b@ to @MSF m a b@+-- for a specific transformer @t@ often gives rise to known FRP constructs.+-- For instance, flattening with 'EitherT' gives rise to switching, and+-- flattening with 'ListT' gives rise to parallelism with broadcasting. ----- For a very detailed introduction to 'MSF's, see:--- <http://dl.acm.org/citation.cfm?id=2976010>--- (mirror: <http://www.cs.nott.ac.uk/~psxip1/#FRPRefactored>).+-- 'MSF's can be used to implement many FRP variants, including Arrowized FRP,+-- Classic FRP, and plain reactive programming. Arrowized and applicative+-- syntax are both supported.+--+-- For a very detailed introduction to 'MSF's, see:+-- <http://dl.acm.org/citation.cfm?id=2976010>+-- (mirror: <http://www.cs.nott.ac.uk/~psxip1/#FRPRefactored>). module Data.MonadicStreamFunction.Core ( -- * Types MSF@@ -57,13 +62,13 @@ import Control.Applicative import Control.Arrow-import Control.Category as C+import Control.Category as C import Control.Monad.Base import Control.Monad.Trans.Class-import Data.Tuple (swap)-import Prelude hiding ((.), id, sum)+import Data.Tuple (swap)+import Prelude hiding (id, sum, (.)) -import Data.MonadicStreamFunction.InternalCore (MSF, morphGS, feedback, reactimate, embed)+import Data.MonadicStreamFunction.InternalCore (MSF, embed, feedback, morphGS, reactimate) -- * Definitions
src/Data/MonadicStreamFunction/Instances/ArrowChoice.hs view
@@ -1,8 +1,13 @@-{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE InstanceSigs #-} {-# OPTIONS_GHC -fno-warn-orphans #-}--- | Instance of 'ArrowChoice' for Monadic Stream Functions ('MSF').+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk ----- Import this module to include that (orphan) instance.+-- Instance of 'ArrowChoice' for Monadic Stream Functions ('MSF').+--+-- Import this module to include that (orphan) instance. module Data.MonadicStreamFunction.Instances.ArrowChoice where import Control.Arrow
src/Data/MonadicStreamFunction/Instances/ArrowLoop.hs view
@@ -1,19 +1,24 @@-{-# LANGUAGE InstanceSigs #-}-{-# LANGUAGE RecursiveDo #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE RecursiveDo #-} {-# OPTIONS_GHC -fno-warn-orphans #-}--- | Instance of 'ArrowLoop' for Monadic Stream Functions ('MSF').+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk ----- Import this module to include that (orphan) instance.+-- Instance of 'ArrowLoop' for Monadic Stream Functions ('MSF'). ----- This is only defined for monads that are instances of 'MonadFix'.+-- Import this module to include that (orphan) instance.+--+-- This is only defined for monads that are instances of 'MonadFix'. module Data.MonadicStreamFunction.Instances.ArrowLoop where -import Data.MonadicStreamFunction.Core-import Data.MonadicStreamFunction.InternalCore- -- External import Control.Arrow import Control.Monad.Fix++import Data.MonadicStreamFunction.Core+import Data.MonadicStreamFunction.InternalCore -- | 'ArrowLoop' instance for MSFs. The monad must be an instance of -- 'MonadFix'.
src/Data/MonadicStreamFunction/Instances/ArrowPlus.hs view
@@ -1,15 +1,20 @@ {-# OPTIONS_GHC -fno-warn-orphans #-}--- | Instance of 'ArrowPlus' for Monadic Stream Functions ('MSF').+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk ----- Import this module to include that (orphan) instance.+-- Instance of 'ArrowPlus' for Monadic Stream Functions ('MSF'). ----- This is only defined for monads that are instances of 'MonadPlus'.+-- Import this module to include that (orphan) instance.+--+-- This is only defined for monads that are instances of 'MonadPlus'. module Data.MonadicStreamFunction.Instances.ArrowPlus where -- base+import Control.Applicative import Control.Arrow import Control.Monad-import Control.Applicative -- dunai import Data.MonadicStreamFunction.Core
src/Data/MonadicStreamFunction/Instances/Num.hs view
@@ -1,10 +1,14 @@-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -fno-warn-orphans #-}---- | Number instances for 'MSF's that produce numbers. This allows you to use--- numeric operators with 'MSF's that output numbers, for example,--- you can write:+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk --+-- Number instances for 'MSF's that produce numbers. This allows you to use+-- numeric operators with 'MSF's that output numbers, for example, you can+-- write:+-- -- @ -- msf1 :: MSF Input Double -- defined however you want -- msf2 :: MSF Input Double -- defined however you want@@ -20,7 +24,6 @@ -- -- Instances are provided for the type classes 'Num', 'Fractional' -- and 'Floating'.- module Data.MonadicStreamFunction.Instances.Num where import Control.Arrow.Util
src/Data/MonadicStreamFunction/Instances/VectorSpace.hs view
@@ -2,8 +2,13 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}--- | 'VectorSpace' instances for 'MSF's that produce vector spaces. This allows+{-# OPTIONS_GHC -fno-warn-orphans #-}+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk+--+-- 'VectorSpace' instances for 'MSF's that produce vector spaces. This allows -- you to use vector operators with 'MSF's that output vectors, for example, you -- can write: --@@ -31,9 +36,11 @@ module Data.MonadicStreamFunction.Instances.VectorSpace where import Control.Arrow+import Data.VectorSpace+ import Control.Arrow.Util+ import Data.MonadicStreamFunction.Core-import Data.VectorSpace -- | Vector-space instance for 'MSF's. instance (Monad m, VectorSpace v s) => VectorSpace (MSF m a v) s where
src/Data/MonadicStreamFunction/InternalCore.hs view
@@ -1,19 +1,24 @@ {-# LANGUAGE ExplicitForAll #-} {-# LANGUAGE Rank2Types #-}--- | Monadic Stream Functions are synchronized stream functions--- with side effects.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk ----- 'MSF's are defined by a function--- @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@--- that executes one step of a simulation, and produces an output in a--- monadic context, and a continuation to be used for future steps.+-- Monadic Stream Functions are synchronized stream functions with side+-- effects. ----- 'MSF's are a generalisation of the implementation mechanism used by Yampa,--- Wormholes and other FRP and reactive implementations.+-- 'MSF's are defined by a function+-- @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@+-- that executes one step of a simulation, and produces an output in a monadic+-- context, and a continuation to be used for future steps. ----- This modules defines only the minimal core. Hopefully, other functions can be--- defined in terms of the functions in this module without accessing the--- MSF constuctor.+-- 'MSF's are a generalisation of the implementation mechanism used by Yampa,+-- Wormholes and other FRP and reactive implementations.+--+-- This modules defines only the minimal core. Hopefully, other functions can+-- be defined in terms of the functions in this module without accessing the+-- MSF constuctor. -- NOTE TO IMPLEMENTORS:@@ -36,17 +41,16 @@ -- having orphan instances'), the main module Data.MonadicStreamFunction -- exports everything. Users should *never* import this module here -- individually, but the main module instead.- module Data.MonadicStreamFunction.InternalCore where -- External-import Control.Arrow import Control.Applicative-import Control.Category (Category(..))+import Control.Arrow+import Control.Category (Category (..)) import Control.Monad import Control.Monad.Base import Control.Monad.Trans.Class-import Prelude hiding ((.), id, sum)+import Prelude hiding (id, sum, (.)) -- * Definitions
src/Data/MonadicStreamFunction/Parallel.hs view
@@ -1,4 +1,9 @@--- | Versions of arrow combinators that run things in parallel using 'par', if+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk+--+-- Versions of arrow combinators that run things in parallel using 'par', if -- possible. module Data.MonadicStreamFunction.Parallel where
src/Data/MonadicStreamFunction/ReactHandle.hs view
@@ -1,9 +1,13 @@--- | 'ReactHandle's.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk --+-- 'ReactHandle's.+-- -- Sometimes it is beneficial to give control to an external main loop, -- for example OpenGL or a hardware-clocked audio server like JACK. -- This module makes Dunai compatible with external main loops.- module Data.MonadicStreamFunction.ReactHandle where -- External@@ -13,7 +17,6 @@ -- Internal import Data.MonadicStreamFunction import Data.MonadicStreamFunction.InternalCore- -- | A storage for the current state of an 'MSF'. -- The 'MSF' may not require input or produce output data,
src/Data/MonadicStreamFunction/Util.hs view
@@ -1,6 +1,11 @@ {-# LANGUAGE Arrows #-} {-# LANGUAGE Rank2Types #-}--- | Useful auxiliary functions and definitions.+-- |+-- Copyright : (c) Ivan Perez and Manuel Baerenz, 2016+-- License : BSD3+-- Maintainer : ivan.perez@keera.co.uk+--+-- Useful auxiliary functions and definitions. module Data.MonadicStreamFunction.Util where -- External@@ -9,14 +14,13 @@ import Control.Monad import Control.Monad.Base import Data.Monoid+import Data.VectorSpace+import Prelude hiding (id, (.)) -- Internal+import Control.Monad.Trans.MSF.State import Data.MonadicStreamFunction.Core import Data.MonadicStreamFunction.Instances.ArrowChoice ()-import Data.VectorSpace-import Prelude hiding (id, (.))--import Control.Monad.Trans.MSF.State -- * Streams and sinks