diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index dc3c98e9..940cb020 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -6,7 +6,7 @@ jobs: build: strategy: matrix: - ghc: ['8.4.4', '8.6.5', '8.8.4', '8.10.7', '9.0.2', '9.2.5', '9.4.5', '9.6.1'] + ghc: ['8.4.4', '8.6.5', '8.8.4', '8.10.7', '9.0.2', '9.2.5', '9.4.5', '9.6.1', '9.8.2', '9.10.1'] os: ['ubuntu-latest', 'macos-latest'] runs-on: ${{ matrix.os }} diff --git a/.gitignore b/.gitignore index 0cab7d45..29495b2e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ dist cabal.sandbox.config +cabal.project.local .cabal-sandbox/ dist-* cabal-dev diff --git a/reflex.cabal b/reflex.cabal index ef0b397c..3fd84ee0 100644 --- a/reflex.cabal +++ b/reflex.cabal @@ -1,510 +1,532 @@ -Name: reflex -Version: 0.9.3.0 -Synopsis: Higher-order Functional Reactive Programming -Description: - Interactive programs without callbacks or side-effects. - Functional Reactive Programming (FRP) uses composable events and time-varying - values to describe interactive systems as pure functions. - Just like other pure functional code, functional reactive code is easier - to get right on the first try, maintain, and reuse. - . - Reflex is a fully-deterministic, higher-order Functional Reactive Programming - interface and an engine that efficiently implements that interface. - . - -License: BSD3 -License-file: LICENSE -Author: Ryan Trinkle -Maintainer: ryan.trinkle@gmail.com -Stability: Experimental -Category: FRP -Build-type: Simple -Cabal-version: 1.22 -homepage: https://reflex-frp.org -bug-reports: https://github.com/reflex-frp/reflex/issues +cabal-version: 1.22 +name: reflex +version: 0.9.3.0 +license: BSD3 +license-file: LICENSE +maintainer: ryan.trinkle@gmail.com +author: Ryan Trinkle +stability: Experimental +tested-with: + ghc ==8.4.4 || ==8.6.5 || ==8.8.1 || ==8.10.7 || ==9.0.1 || ==9.2.5 || ==9.4.5 || ==9.6.1 || ==9.8.2 || ==9.10.1 + ghcjs ==8.6 || ==8.10 + +homepage: https://reflex-frp.org +bug-reports: https://github.com/reflex-frp/reflex/issues +synopsis: Higher-order Functional Reactive Programming +description: + Interactive programs without callbacks or side-effects. + Functional Reactive Programming (FRP) uses composable events and time-varying + values to describe interactive systems as pure functions. + Just like other pure functional code, functional reactive code is easier + to get right on the first try, maintain, and reuse. + . + Reflex is a fully-deterministic, higher-order Functional Reactive Programming + interface and an engine that efficiently implements that interface. + . + + +category: FRP +build-type: Simple extra-source-files: - README.md - Quickref.md - ChangeLog.md + README.md + Quickref.md + ChangeLog.md -tested-with: - GHC ==8.4.4 || ==8.6.5 || ==8.8.1 || ==8.10.7 || ==9.0.1 || ==9.2.5 || ==9.4.5 || ==9.6.1, - GHCJS ==8.6 || ==8.10 +source-repository head + type: git + location: https://github.com/reflex-frp/reflex flag use-reflex-optimizer - description: Use the GHC plugin Reflex.Optimizer on some of the modules in the package. This is still experimental. - default: False - manual: True + description: + Use the GHC plugin Reflex.Optimizer on some of the modules in the package. This is still experimental. + + default: False + manual: True flag use-template-haskell - description: Use template haskell to generate lenses - default: True - manual: True + description: Use template haskell to generate lenses + manual: True flag debug-trace-events - description: Add instrumentation that outputs the stack trace of the definition of an event whenever it is subscribed to. Warning: It is very slow! - default: False - manual: True + description: + Add instrumentation that outputs the stack trace of the definition of an event whenever it is subscribed to. Warning: It is very slow! + + default: False + manual: True flag fast-weak - description: Use the primitive implementation of FastWeak in GHCJS; note that this requires GHCJS to be built with FastWeak and FastWeakBag present in the RTS, which is not the default - default: False - manual: True + description: + Use the primitive implementation of FastWeak in GHCJS; note that this requires GHCJS to be built with FastWeak and FastWeakBag present in the RTS, which is not the default + + default: False + manual: True flag debug-propagation - description: Enable debugging of spider internals - default: False - manual: True + description: Enable debugging of spider internals + default: False + manual: True flag debug-cycles - description: Enable debugging of event cycles - default: False - manual: True + description: Enable debugging of event cycles + default: False + manual: True flag split-these - description: Use split these/semialign packages - manual: False - default: True + description: Use split these/semialign packages library - default-language: Haskell2010 - hs-source-dirs: src - build-depends: - MemoTrie == 0.6.*, - base >= 4.11 && <= 4.21, - bifunctors >= 5.2 && < 5.7, - comonad >= 5.0.4 && < 5.1, - commutative-semigroups >= 0.1 && <= 0.2.0.1, - constraints >= 0.10 && <= 0.14.2, - constraints-extras >= 0.3 && < 0.5, - containers >= 0.6 && <= 0.7, - data-default >= 0.5 && < 0.8, - dependent-map >= 0.3 && < 0.5, - exceptions >= 0.10 && < 0.11, - exception-transformers >= 0.4 && < 0.5, - lens >= 4.7 && <= 5.3.2, - mmorph >= 1.0 && < 1.3, - monad-control >= 1.0.1 && < 1.1, - mtl >= 2.1 && < 2.4, - patch >= 0.0.7 && < 0.1, - prim-uniq >= 0.1.0.1 && < 0.3, - primitive >= 0.5 && <= 0.9.1.0, - profunctors >= 5.3 && < 5.7, - random >= 1.1 && < 1.3, - ref-tf >= 0.4 && < 0.6, - reflection == 2.1.*, - semigroupoids >= 4.0 && < 7, - stm >= 2.4 && < 2.6, - syb >= 0.5 && < 0.8, - time >= 1.4 && < 1.13, - transformers >= 0.5 && < 0.7, - unbounded-delays >= 0.1.0.0 && < 0.2, - witherable >= 0.4 && < 0.5 - - if flag(split-these) - build-depends: these >= 1 && <1.3, - semialign >=1 && <1.4, - monoidal-containers >= 0.6.2.0 && < 0.7 - else - build-depends: these >= 0.4 && <0.9, - monoidal-containers == 0.4.0.0 - - exposed-modules: - Control.Monad.ReaderIO - Data.AppendMap, - Data.FastMutableIntMap, - Data.FastWeakBag, - Data.Map.Misc, - Data.WeakBag, - Reflex, - Reflex.Class, - Reflex.Adjustable.Class, - Reflex.BehaviorWriter.Base, - Reflex.BehaviorWriter.Class, - Reflex.Collection, - Reflex.Dynamic, - Reflex.Dynamic.Uniq, - Reflex.DynamicWriter, - Reflex.DynamicWriter.Base, - Reflex.DynamicWriter.Class, - Reflex.EventWriter, - Reflex.EventWriter.Base, - Reflex.EventWriter.Class, - Reflex.FastWeak, - Reflex.FunctorMaybe, - Reflex.Host.Class, - Reflex.Host.Headless, - Reflex.Network, - Reflex.NotReady.Class, - Reflex.PerformEvent.Base, - Reflex.PerformEvent.Class, - Reflex.PostBuild.Base, - Reflex.PostBuild.Class, - Reflex.Profiled, - Reflex.Pure, - Reflex.Query.Base, - Reflex.Query.Class, - Reflex.Requester.Base, - Reflex.Requester.Base.Internal, - Reflex.Requester.Class, - Reflex.Spider, - Reflex.Spider.Internal, - Reflex.Time, - Reflex.TriggerEvent.Base, - Reflex.TriggerEvent.Class, - Reflex.Widget.Basic, - Reflex.Workflow - - reexported-modules: - patch:Data.Functor.Misc, - patch:Data.Patch as Reflex.Patch, - patch:Data.Patch.Class as Reflex.Patch.Class, - patch:Data.Patch.DMap as Reflex.Patch.DMap, - patch:Data.Patch.DMapWithMove as Reflex.Patch.DMapWithMove, - patch:Data.Patch.IntMap as Reflex.Patch.IntMap, - patch:Data.Patch.Map as Reflex.Patch.Map, - patch:Data.Patch.MapWithMove as Reflex.Patch.MapWithMove - - ghc-options: -Wall -fwarn-redundant-constraints -fwarn-tabs -funbox-strict-fields -O2 -fspecialise-aggressively - - if flag(debug-trace-events) - cpp-options: -DDEBUG_TRACE_EVENTS - build-depends: - bytestring >= 0.10.8 && < 0.11 - - if flag(use-reflex-optimizer) - cpp-options: -DUSE_REFLEX_OPTIMIZER - build-depends: ghc - exposed-modules: Reflex.Optimizer - - if flag(debug-propagation) - cpp-options: -DDEBUG -DDEBUG_TRACE_PROPAGATION -DDEBUG_TRACE_INVALIDATION - - if flag(debug-cycles) - cpp-options: -DDEBUG_CYCLES - - if flag(use-template-haskell) - cpp-options: -DUSE_TEMPLATE_HASKELL - build-depends: - dependent-sum >= 0.6 && < 0.8, - haskell-src-exts >= 1.16 && < 1.24, - haskell-src-meta >= 0.6 && < 0.9, - template-haskell >= 2.9 && <= 2.22.0.0 exposed-modules: - Reflex.Dynamic.TH - other-extensions: TemplateHaskell - else - build-depends: - dependent-sum >= 0.6 && < 0.8 - - if flag(fast-weak) && impl(ghcjs) - cpp-options: -DGHCJS_FAST_WEAK + Control.Monad.ReaderIO + Data.AppendMap + Data.FastMutableIntMap + Data.FastWeakBag + Data.Map.Misc + Data.WeakBag + Reflex + Reflex.Class + Reflex.Adjustable.Class + Reflex.BehaviorWriter.Base + Reflex.BehaviorWriter.Class + Reflex.Collection + Reflex.Dynamic + Reflex.Dynamic.Uniq + Reflex.DynamicWriter + Reflex.DynamicWriter.Base + Reflex.DynamicWriter.Class + Reflex.EventWriter + Reflex.EventWriter.Base + Reflex.EventWriter.Class + Reflex.FastWeak + Reflex.FunctorMaybe + Reflex.Host.Class + Reflex.Host.Headless + Reflex.Network + Reflex.NotReady.Class + Reflex.PerformEvent.Base + Reflex.PerformEvent.Class + Reflex.PostBuild.Base + Reflex.PostBuild.Class + Reflex.Profiled + Reflex.Pure + Reflex.Query.Base + Reflex.Query.Class + Reflex.Requester.Base + Reflex.Requester.Base.Internal + Reflex.Requester.Class + Reflex.Spider + Reflex.Spider.Internal + Reflex.Time + Reflex.TriggerEvent.Base + Reflex.TriggerEvent.Class + Reflex.Widget.Basic + Reflex.Workflow + + reexported-modules: + patch:Data.Functor.Misc, + patch:Data.Patch as Reflex.Patch, + patch:Data.Patch.Class as Reflex.Patch.Class, + patch:Data.Patch.DMap as Reflex.Patch.DMap, + patch:Data.Patch.DMapWithMove as Reflex.Patch.DMapWithMove, + patch:Data.Patch.IntMap as Reflex.Patch.IntMap, + patch:Data.Patch.Map as Reflex.Patch.Map, + patch:Data.Patch.MapWithMove as Reflex.Patch.MapWithMove + + hs-source-dirs: src + default-language: Haskell2010 + ghc-options: + -Wall -fwarn-redundant-constraints -fwarn-tabs + -funbox-strict-fields -O2 -fspecialise-aggressively - if impl(ghcjs) build-depends: - ghcjs-base == 0.2.* + MemoTrie >=0.6 && <0.7, + base >=4.11 && <4.21, + bifunctors >=5.2 && <5.7, + comonad >=5.0.4 && <5.1, + commutative-semigroups >=0.1 && <0.3, + constraints >=0.10 && <0.15, + constraints-extras >=0.3 && <0.5, + containers >=0.6 && <0.8, + data-default >=0.5 && <0.8, + dependent-map >=0.3 && <0.5, + exceptions >=0.10 && <0.11, + exception-transformers >=0.4 && <0.5, + lens >=4.7 && <5.4, + mmorph >=1.0 && <1.3, + monad-control >=1.0.1 && <1.1, + mtl >=2.1 && <2.4, + patch >=0.0.7 && <0.1, + prim-uniq >=0.1.0.1 && <0.3, + primitive >=0.5 && <0.10, + profunctors >=5.3 && <5.7, + random >=1.1 && <1.3, + ref-tf >=0.4 && <0.6, + reflection >=2.1 && <2.2, + semigroupoids >=4.0 && <7, + stm >=2.4 && <2.6, + syb >=0.5 && <0.8, + time >=1.4 && <1.13, + transformers >=0.5 && <0.7, + unbounded-delays >=0.1.0.0 && <0.2, + witherable >=0.4 && <0.6 + + if flag(split-these) + build-depends: + these >=1 && <1.3, + semialign >=1 && <1.4, + monoidal-containers >=0.6.2.0 && <0.7 + + else + build-depends: + these >=0.4 && <0.9, + monoidal-containers ==0.4.0.0 + + if flag(debug-trace-events) + cpp-options: -DDEBUG_TRACE_EVENTS + build-depends: bytestring >=0.10.8 && <0.11 + + if flag(use-reflex-optimizer) + exposed-modules: Reflex.Optimizer + cpp-options: -DUSE_REFLEX_OPTIMIZER + build-depends: ghc + + if flag(debug-propagation) + cpp-options: + -DDEBUG -DDEBUG_TRACE_PROPAGATION -DDEBUG_TRACE_INVALIDATION + + if flag(debug-cycles) + cpp-options: -DDEBUG_CYCLES + + if flag(use-template-haskell) + exposed-modules: Reflex.Dynamic.TH + cpp-options: -DUSE_TEMPLATE_HASKELL + other-extensions: TemplateHaskell + build-depends: + dependent-sum >=0.6 && <0.8, + haskell-src-exts >=1.16 && <1.24, + haskell-src-meta >=0.6 && <0.9, + template-haskell >=2.9 && <=2.22.0.0 + + else + build-depends: dependent-sum >=0.6 && <0.8 + + if (flag(fast-weak) && impl(ghcjs >=0)) + cpp-options: -DGHCJS_FAST_WEAK + + if impl(ghcjs >=0) + build-depends: ghcjs-base >=0.2 && <0.3 test-suite semantics - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: semantics.hs - hs-source-dirs: test - ghc-options: -O2 -Wall -rtsopts - build-depends: - base, - bifunctors, - containers, - deepseq, - dependent-map, - dependent-sum, - mtl, - ref-tf, - reflex, - split, - transformers - other-modules: - Reflex.Bench.Focused - Reflex.Plan.Pure - Reflex.Plan.Reflex - Reflex.Test - Reflex.Test.Micro - Reflex.TestPlan + type: exitcode-stdio-1.0 + main-is: semantics.hs + hs-source-dirs: test + other-modules: + Reflex.Bench.Focused + Reflex.Plan.Pure + Reflex.Plan.Reflex + Reflex.Test + Reflex.Test.Micro + Reflex.TestPlan + + default-language: Haskell2010 + ghc-options: -O2 -Wall -rtsopts + build-depends: + base, + bifunctors <5.7, + containers, + deepseq, + dependent-map <0.5, + dependent-sum <0.8, + mtl, + ref-tf <0.6, + reflex, + split <0.3, + transformers test-suite CrossImpl - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: Reflex/Test/CrossImpl.hs - hs-source-dirs: test - ghc-options: -O2 -Wall -rtsopts - build-depends: - base, - containers, - dependent-map, - dependent-sum, - deepseq, - mtl, - transformers, - ref-tf, - reflex - other-modules: - Reflex.Test - Reflex.TestPlan - Reflex.Plan.Reflex - Reflex.Plan.Pure + type: exitcode-stdio-1.0 + main-is: Reflex/Test/CrossImpl.hs + hs-source-dirs: test + other-modules: + Reflex.Test + Reflex.TestPlan + Reflex.Plan.Reflex + Reflex.Plan.Pure + + default-language: Haskell2010 + ghc-options: -O2 -Wall -rtsopts + build-depends: + base, + containers, + dependent-map <0.5, + dependent-sum <0.8, + deepseq, + mtl, + transformers, + ref-tf <0.6, + reflex test-suite hlint - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: hlint.hs - hs-source-dirs: test - build-depends: base - , directory - , filepath - , filemanip - if impl(ghc >= 9.6) - buildable: False - if impl(ghc < 9.2) - build-depends: hlint (< 2.1 || >= 2.2.2) && < 3.5 - else - build-depends: hlint >= 3.5 && < 3.6 - if impl(ghcjs) || arch(javascript) - buildable: False + type: exitcode-stdio-1.0 + main-is: hlint.hs + hs-source-dirs: test + default-language: Haskell2010 + build-depends: + base, + directory, + filepath, + filemanip -test-suite EventWriterT - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: EventWriterT.hs - hs-source-dirs: test - build-depends: base - , containers - , deepseq - , dependent-map - , dependent-sum - , lens - , mtl - , these - , transformers - , reflex - , ref-tf - - if flag(split-these) - build-depends: these-lens - - other-modules: - Test.Run + if impl(ghc >=9.6) + buildable: False + if impl(ghc <9.2) + build-depends: hlint (<2.1 || >=2.2.2) && <3.5 -test-suite DebugCycles - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: DebugCycles.hs - hs-source-dirs: test - ghc-options: -threaded - build-depends: base - , containers - , deepseq - , dependent-map - , dependent-sum - , hspec - , lens - , mtl - , these - , transformers - , reflex - , ref-tf - , witherable - , proctest - - - if flag(split-these) - build-depends: these-lens, semialign - - other-modules: - Test.Run + else + build-depends: hlint >=3.5 && <3.6 + if (impl(ghcjs >=0) || arch(javascript)) + buildable: False + +test-suite EventWriterT + type: exitcode-stdio-1.0 + main-is: EventWriterT.hs + hs-source-dirs: test + other-modules: Test.Run + default-language: Haskell2010 + build-depends: + base, + containers, + deepseq, + dependent-map <0.5, + dependent-sum <0.8, + lens <5.4, + mtl, + these <1.3, + transformers, + reflex, + ref-tf <0.6 + + if flag(split-these) + build-depends: these-lens <1.1 + +test-suite DebugCycles + type: exitcode-stdio-1.0 + main-is: DebugCycles.hs + hs-source-dirs: test + other-modules: Test.Run + default-language: Haskell2010 + ghc-options: -threaded + build-depends: + base, + containers, + deepseq, + dependent-map <0.5, + dependent-sum <0.8, + hspec <2.12, + lens <5.4, + mtl, + these <1.3, + transformers, + reflex, + ref-tf <0.6, + witherable <0.6, + proctest <0.2 + + if flag(split-these) + build-depends: + these-lens <1.1, + semialign <1.4 test-suite RequesterT - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: RequesterT.hs - hs-source-dirs: test - build-depends: base - , constraints - , constraints-extras - , containers - , deepseq - , dependent-map - , dependent-sum - , lens - , mtl - , ref-tf - , reflex - , text - , these - , transformers - - if flag(split-these) - build-depends: these-lens - - other-modules: - Reflex.TestPlan - Reflex.Plan.Pure - Test.Run + type: exitcode-stdio-1.0 + main-is: RequesterT.hs + hs-source-dirs: test + other-modules: + Reflex.TestPlan + Reflex.Plan.Pure + Test.Run + + default-language: Haskell2010 + build-depends: + base, + constraints <0.15, + constraints-extras <0.5, + containers, + deepseq, + dependent-map <0.5, + dependent-sum <0.8, + lens <5.4, + mtl, + ref-tf <0.6, + reflex, + text, + these <1.3, + transformers + + if flag(split-these) + build-depends: these-lens <1.1 test-suite Headless - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: Headless.hs - hs-source-dirs: test - build-depends: base - , reflex + type: exitcode-stdio-1.0 + main-is: Headless.hs + hs-source-dirs: test + default-language: Haskell2010 + build-depends: + base, + reflex test-suite Adjustable - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: Adjustable.hs - hs-source-dirs: test - build-depends: base - , containers - , dependent-sum - , reflex - , ref-tf - , these - - other-modules: - Test.Run + type: exitcode-stdio-1.0 + main-is: Adjustable.hs + hs-source-dirs: test + other-modules: Test.Run + default-language: Haskell2010 + build-depends: + base, + containers, + dependent-sum <0.8, + reflex, + ref-tf <0.6, + these <1.3 test-suite QueryT - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: QueryT.hs - hs-source-dirs: test - build-depends: base - , commutative-semigroups - , containers - , dependent-map - , dependent-sum - , deepseq - , lens - , monoidal-containers - , mtl - , patch - , ref-tf - , reflex - , these - , transformers - - if flag(split-these) - build-depends: semialign, these-lens - - other-modules: - Test.Run - Reflex.TestPlan - Reflex.Plan.Reflex - Reflex.Plan.Pure + type: exitcode-stdio-1.0 + main-is: QueryT.hs + hs-source-dirs: test + other-modules: + Test.Run + Reflex.TestPlan + Reflex.Plan.Reflex + Reflex.Plan.Pure + + default-language: Haskell2010 + build-depends: + base, + commutative-semigroups <0.3, + containers, + dependent-map <0.5, + dependent-sum <0.8, + deepseq, + lens <5.4, + monoidal-containers <0.7, + mtl, + patch <0.1, + ref-tf <0.6, + reflex, + these <1.3, + transformers + + if flag(split-these) + build-depends: + semialign <1.4, + these-lens <1.1 test-suite GC-Semantics - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: GC.hs - hs-source-dirs: test - build-depends: base - , containers - , dependent-sum - , dependent-map - , deepseq - , mtl - , patch - , these - , transformers - , reflex - , ref-tf - - if flag(split-these) - build-depends: semialign - - other-modules: - Reflex.Plan.Pure - Reflex.Plan.Reflex - Reflex.TestPlan - Test.Run + type: exitcode-stdio-1.0 + main-is: GC.hs + hs-source-dirs: test + other-modules: + Reflex.Plan.Pure + Reflex.Plan.Reflex + Reflex.TestPlan + Test.Run + + default-language: Haskell2010 + build-depends: + base, + containers, + dependent-sum <0.8, + dependent-map <0.5, + deepseq, + mtl, + patch <0.1, + these <1.3, + transformers, + reflex, + ref-tf <0.6 + + if flag(split-these) + build-depends: semialign <1.4 test-suite rootCleanup - default-language: Haskell2010 - type: exitcode-stdio-1.0 - main-is: rootCleanup.hs - hs-source-dirs: test - build-depends: base - , containers - , deepseq - , dependent-sum - , mtl - , reflex - , ref-tf - , these - other-modules: - Reflex.Plan.Pure - Reflex.TestPlan - Test.Run + type: exitcode-stdio-1.0 + main-is: rootCleanup.hs + hs-source-dirs: test + other-modules: + Reflex.Plan.Pure + Reflex.TestPlan + Test.Run + + default-language: Haskell2010 + build-depends: + base, + containers, + deepseq, + dependent-sum <0.8, + mtl, + reflex, + ref-tf <0.6, + these <1.3 benchmark spider-bench - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: bench test - main-is: Main.hs - ghc-options: -Wall -O2 -rtsopts - build-depends: - base, - containers, - criterion, - deepseq, - dependent-map, - dependent-sum, - ref-tf, - mtl, - primitive, - reflex, - split, - stm, - transformers - other-modules: - Reflex.TestPlan - Reflex.Plan.Reflex - Reflex.Bench.Focused - if arch(javascript) - buildable: False + type: exitcode-stdio-1.0 + main-is: Main.hs + hs-source-dirs: bench test + other-modules: + Reflex.TestPlan + Reflex.Plan.Reflex + Reflex.Bench.Focused + + default-language: Haskell2010 + ghc-options: -Wall -O2 -rtsopts + build-depends: + base, + containers, + criterion <1.7, + deepseq, + dependent-map <0.5, + dependent-sum <0.8, + ref-tf <0.6, + mtl, + primitive <0.10, + reflex, + split <0.3, + stm, + transformers + + if arch(javascript) + buildable: False benchmark saulzar-bench - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: bench test - c-sources: bench-cbits/checkCapability.c - main-is: RunAll.hs - ghc-options: -Wall -O2 -rtsopts -threaded - build-depends: - base, - containers, - criterion, - deepseq, - dependent-map, - dependent-sum, - loch-th, - mtl, - primitive, - process, - ref-tf, - reflex, - split, - stm, - time, - transformers - other-modules: - Reflex.TestPlan - Reflex.Plan.Reflex - Reflex.Bench.Focused - if arch(javascript) - buildable: False - -source-repository head - type: git - location: https://github.com/reflex-frp/reflex + type: exitcode-stdio-1.0 + main-is: RunAll.hs + c-sources: bench-cbits/checkCapability.c + hs-source-dirs: bench test + other-modules: + Reflex.TestPlan + Reflex.Plan.Reflex + Reflex.Bench.Focused + + default-language: Haskell2010 + ghc-options: -Wall -O2 -rtsopts -threaded + build-depends: + base, + containers, + criterion <1.7, + deepseq, + dependent-map <0.5, + dependent-sum <0.8, + loch-th <0.3, + mtl, + primitive <0.10, + process, + ref-tf <0.6, + reflex, + split <0.3, + stm, + time, + transformers + + if arch(javascript) + buildable: False diff --git a/src/Control/Monad/ReaderIO.hs b/src/Control/Monad/ReaderIO.hs index ad235fe7..33d58ff5 100644 --- a/src/Control/Monad/ReaderIO.hs +++ b/src/Control/Monad/ReaderIO.hs @@ -2,16 +2,12 @@ {-# language MultiParamTypeClasses #-} {-# language FlexibleInstances #-} {-# language CPP #-} + module Control.Monad.ReaderIO - ( - ReaderIO (..) - ) - where + ( ReaderIO (..) + ) where import Control.Monad.Fix -#if MIN_VERSION_base(4,10,0) -import Control.Applicative -#endif import Control.Monad import Control.Monad.Reader.Class import Control.Monad.IO.Class diff --git a/src/Data/AppendMap.hs b/src/Data/AppendMap.hs index 4bfd8e0c..5bbd379a 100644 --- a/src/Data/AppendMap.hs +++ b/src/Data/AppendMap.hs @@ -7,6 +7,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -fno-warn-orphans #-} + -- | -- Module: -- Data.AppendMap @@ -30,9 +31,7 @@ import qualified Data.Map.Internal.Debug as Map (showTree, showTreeWith) #else import qualified Data.Map as Map (showTree, showTreeWith) #endif -import qualified Data.Witherable as W import Data.Map.Monoidal -import qualified Data.Map.Monoidal as MonoidalMap {-# DEPRECATED AppendMap "Use 'MonoidalMap' instead" #-} diff --git a/src/Data/FastMutableIntMap.hs b/src/Data/FastMutableIntMap.hs index d46c6a24..640a7b61 100644 --- a/src/Data/FastMutableIntMap.hs +++ b/src/Data/FastMutableIntMap.hs @@ -1,4 +1,5 @@ {-# LANGUAGE TypeFamilies #-} + -- | -- Module: -- Data.FastMutableIntMap @@ -94,4 +95,4 @@ applyPatch (FastMutableIntMap r) p@(PatchIntMap m) = do return $ IntMap.intersection v m toList :: FastMutableIntMap a -> IO [(Int, a)] -toList (FastMutableIntMap r) = IntMap.toList <$> readIORef r \ No newline at end of file +toList (FastMutableIntMap r) = IntMap.toList <$> readIORef r diff --git a/src/Data/FastWeakBag.hs b/src/Data/FastWeakBag.hs index 2fe8068b..ae97a6a8 100644 --- a/src/Data/FastWeakBag.hs +++ b/src/Data/FastWeakBag.hs @@ -7,6 +7,7 @@ {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE JavaScriptFFI #-} #endif + -- | This module defines the 'FastWeakBag' type, which represents a mutable -- collection of items that does not cause the items to be retained in memory. -- This is useful for situations where a value needs to be inspected or modified diff --git a/src/Data/Map/Misc.hs b/src/Data/Map/Misc.hs index a41010da..afdfc282 100644 --- a/src/Data/Map/Misc.hs +++ b/src/Data/Map/Misc.hs @@ -1,4 +1,5 @@ {-# LANGUAGE LambdaCase #-} + -- | Additional functions for manipulating 'Map's. module Data.Map.Misc ( diff --git a/src/Data/WeakBag.hs b/src/Data/WeakBag.hs index cbd01ef1..fd70ec2a 100644 --- a/src/Data/WeakBag.hs +++ b/src/Data/WeakBag.hs @@ -4,6 +4,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + -- | This module defines the 'WeakBag' type, which represents a mutable -- collection of items that does not cause the items to be retained in memory. -- This is useful for situations where a value needs to be inspected or modified diff --git a/src/Reflex.hs b/src/Reflex.hs index 1529280b..8e177825 100644 --- a/src/Reflex.hs +++ b/src/Reflex.hs @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} + -- | This module exports all of the commonly-used functionality of Reflex; if -- you are just getting started with Reflex, this is probably what you want. module Reflex diff --git a/src/Reflex/Adjustable/Class.hs b/src/Reflex/Adjustable/Class.hs index c58e3f28..4d428e04 100644 --- a/src/Reflex/Adjustable/Class.hs +++ b/src/Reflex/Adjustable/Class.hs @@ -10,6 +10,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + -- | -- Module: -- Reflex.Adjustable.Class diff --git a/src/Reflex/BehaviorWriter/Base.hs b/src/Reflex/BehaviorWriter/Base.hs index 520d8602..802c7b22 100644 --- a/src/Reflex/BehaviorWriter/Base.hs +++ b/src/Reflex/BehaviorWriter/Base.hs @@ -10,11 +10,13 @@ Description: Implementation of BehaviorWriter {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE StandaloneDeriving #-} #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.BehaviorWriter.Base ( BehaviorWriterT (..) , runBehaviorWriterT @@ -25,7 +27,6 @@ import Control.Monad import Control.Monad.Catch (MonadMask, MonadThrow, MonadCatch) import Control.Monad.Exception import Control.Monad.Fix -import Control.Monad.Identity import Control.Monad.IO.Class import Control.Monad.Morph import Control.Monad.Reader @@ -40,6 +41,10 @@ import Data.Map (Map) import qualified Data.Map as Map import Data.Some (Some) +#if !MIN_VERSION_base(4,18,0) +import Control.Monad.Identity +#endif + import Reflex.Class import Reflex.Adjustable.Class import Reflex.BehaviorWriter.Class diff --git a/src/Reflex/BehaviorWriter/Class.hs b/src/Reflex/BehaviorWriter/Class.hs index bff3a4b4..dfc08e2b 100644 --- a/src/Reflex/BehaviorWriter/Class.hs +++ b/src/Reflex/BehaviorWriter/Class.hs @@ -10,6 +10,7 @@ Description: This module defines the 'BehaviorWriter' class #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.BehaviorWriter.Class ( MonadBehaviorWriter , BehaviorWriter(..) diff --git a/src/Reflex/Class.hs b/src/Reflex/Class.hs index 128ac493..a9cc29f8 100644 --- a/src/Reflex/Class.hs +++ b/src/Reflex/Class.hs @@ -204,7 +204,6 @@ import qualified Data.Dependent.Map as DMap import Data.Functor.Compose import Data.Functor.Product import Data.GADT.Compare (GEq (..), GCompare (..)) -import Data.FastMutableIntMap (PatchIntMap) import Data.Foldable import Data.Functor.Bind import Data.Functor.Misc @@ -220,12 +219,12 @@ import Data.String import Data.These import Data.Type.Coercion import Data.Type.Equality ((:~:) (..)) -import Data.Witherable (Filterable(..)) -import qualified Data.Witherable as W import Reflex.FunctorMaybe (FunctorMaybe) import qualified Reflex.FunctorMaybe import Data.Patch import qualified Data.Patch.MapWithMove as PatchMapWithMove +import Witherable (Filterable(..)) +import qualified Witherable as W import Debug.Trace (trace) @@ -679,15 +678,12 @@ instance (Reflex t, IsString a) => IsString (Behavior t a) where instance Reflex t => Monad (Behavior t) where a >>= f = pull $ sample a >>= sample . f - -- Note: it is tempting to write (_ >> b = b); however, this would result in (fail x >> return y) succeeding (returning y), which violates the law that (a >> b = a >>= \_ -> b), since the implementation of (>>=) above actually will fail. Since we can't examine 'Behavior's other than by using sample, I don't think it's possible to write (>>) to be more efficient than the (>>=) above. - return = constant #if !MIN_VERSION_base(4,13,0) fail = error "Monad (Behavior t) does not support fail" #endif instance (Reflex t, Monoid a) => Monoid (Behavior t a) where mempty = constant mempty - mappend a b = pull $ liftM2 mappend (sample a) (sample b) mconcat = pull . fmap mconcat . mapM sample instance (Reflex t, Num a) => Num (Behavior t a) where @@ -1159,7 +1155,6 @@ instance (Reflex t, Semigroup a) => Semigroup (Dynamic t a) where instance (Reflex t, Monoid a) => Monoid (Dynamic t a) where mconcat = distributeListOverDynWith mconcat mempty = constDyn mempty - mappend = zipDynWith mappend -- | This function converts a 'DMap' whose elements are 'Dynamic's into a -- 'Dynamic' 'DMap'. Its implementation is more efficient than doing the same diff --git a/src/Reflex/Collection.hs b/src/Reflex/Collection.hs index 770ea4b6..37c02446 100644 --- a/src/Reflex/Collection.hs +++ b/src/Reflex/Collection.hs @@ -10,6 +10,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + -- | -- Module: -- Reflex.Collection @@ -36,7 +37,6 @@ import Data.Zip (Zip (..)) import Control.Monad import Control.Monad.Fix -import Control.Monad.Identity import Data.Align import Data.Functor.Misc import Data.Map (Map) @@ -44,6 +44,10 @@ import qualified Data.Map as Map import Data.Map.Misc import Data.These +#if !MIN_VERSION_base(4,18,0) +import Control.Monad.Identity +#endif + import Reflex.Class import Reflex.Adjustable.Class import Reflex.Dynamic diff --git a/src/Reflex/Dynamic.hs b/src/Reflex/Dynamic.hs index 4df27298..74c93ba0 100644 --- a/src/Reflex/Dynamic.hs +++ b/src/Reflex/Dynamic.hs @@ -17,6 +17,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + -- | -- Module: -- Reflex.Dynamic @@ -78,29 +79,30 @@ module Reflex.Dynamic , unsafeDynamic ) where -import Data.Functor.Compose -import Data.Functor.Misc -import Reflex.Class - -import Control.Monad import Control.Monad.Fix import Control.Monad.Identity import Data.Align import Data.Dependent.Map (DMap) import qualified Data.Dependent.Map as DMap import Data.Dependent.Sum (DSum (..)) +import Data.Functor.Compose +import Data.Functor.Misc import Data.GADT.Compare (GCompare (..), GEq (..), GOrdering (..)) import Data.IntMap (IntMap) -import qualified Data.IntMap as IntMap import Data.Kind (Type) import Data.Map (Map) import Data.Maybe -import Data.Monoid ((<>)) import Data.These import Data.Type.Equality ((:~:) (..)) - import Debug.Trace hiding (traceEventWith) +#if !MIN_VERSION_base(4,18,0) +import Control.Monad +import Data.Monoid ((<>)) +#endif + +import Reflex.Class + -- | Map a sampling function over a 'Dynamic'. mapDynM :: forall t m a b. (Reflex t, MonadHold t m) => (forall m'. MonadSample t m' => a -> m' b) -> Dynamic t a -> m (Dynamic t b) mapDynM f d = buildDynamic (f =<< sample (current d)) $ pushAlways f (updated d) diff --git a/src/Reflex/Dynamic/TH.hs b/src/Reflex/Dynamic/TH.hs index b7759bef..d40dd11e 100644 --- a/src/Reflex/Dynamic/TH.hs +++ b/src/Reflex/Dynamic/TH.hs @@ -8,6 +8,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + -- | Template Haskell helper functions for building complex 'Dynamic' values. module Reflex.Dynamic.TH ( qDynPure @@ -15,18 +16,21 @@ module Reflex.Dynamic.TH , mkDynPure ) where -import Reflex.Dynamic - import Control.Monad.State import Data.Data import Data.Generics -import Data.Monoid ((<>)) import qualified Language.Haskell.Exts as Hs import qualified Language.Haskell.Meta.Syntax.Translate as Hs import Language.Haskell.TH import Language.Haskell.TH.Quote import qualified Language.Haskell.TH.Syntax as TH +#if !MIN_VERSION_base(4,18,0) +import Data.Monoid ((<>)) +#endif + +import Reflex.Dynamic + -- | Quote a 'Dynamic' expression. Within the quoted expression, you can use -- @$(unqDyn [| x |])@ to refer to any expression @x@ of type @Dynamic t a@; the -- unquoted result will be of type @a@ diff --git a/src/Reflex/Dynamic/Uniq.hs b/src/Reflex/Dynamic/Uniq.hs index e118af9d..8c2e6ba0 100644 --- a/src/Reflex/Dynamic/Uniq.hs +++ b/src/Reflex/Dynamic/Uniq.hs @@ -5,6 +5,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + -- | This module provides a variation of 'Dynamic' values that uses cheap -- pointer equality checks to reduce the amount of signal propagation needed. module Reflex.Dynamic.Uniq @@ -14,8 +15,12 @@ module Reflex.Dynamic.Uniq , alreadyUniqDynamic ) where -import Control.Applicative (Applicative (..)) import GHC.Exts + +#if !MIN_VERSION_base(4,18,0) +import Control.Monad.Applicative (Applicative(..)) +#endif + import Reflex.Class -- | A 'Dynamic' whose 'updated' 'Event' will never fire with the same value as @@ -101,5 +106,3 @@ instance Reflex t => Applicative (UniqDynamic t) where instance Reflex t => Monad (UniqDynamic t) where UniqDynamic x >>= f = uniqDynamic $ x >>= unUniqDynamic . f - _ >> b = b - return = pure diff --git a/src/Reflex/DynamicWriter/Base.hs b/src/Reflex/DynamicWriter/Base.hs index 912aea3d..6742e22a 100644 --- a/src/Reflex/DynamicWriter/Base.hs +++ b/src/Reflex/DynamicWriter/Base.hs @@ -8,11 +8,13 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE StandaloneDeriving #-} #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.DynamicWriter.Base ( DynamicWriterT (..) , runDynamicWriterT @@ -23,7 +25,6 @@ import Control.Monad import Control.Monad.Catch (MonadMask, MonadThrow, MonadCatch) import Control.Monad.Exception import Control.Monad.Fix -import Control.Monad.Identity import Control.Monad.IO.Class import Control.Monad.Morph import Control.Monad.Primitive @@ -39,10 +40,14 @@ import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap import Data.Map (Map) import qualified Data.Map as Map -import Data.Semigroup (Semigroup(..)) import Data.Some (Some) import Data.These +#if !MIN_VERSION_base(4,18,0) +import Control.Monad.Identity +import Data.Semigroup (Semigroup(..)) +#endif + import Reflex.Adjustable.Class import Reflex.Class import Reflex.DynamicWriter.Class @@ -225,7 +230,7 @@ traverseIntMapWithKeyWithAdjustImpl base mergeMyDynIncremental f (dm0 :: IntMap return (liftedResult0, liftedResult') -- | Map a function over the output of a 'DynamicWriterT'. -withDynamicWriterT :: (Monoid w, Monoid w', Reflex t, MonadHold t m, MonadFix m) +withDynamicWriterT :: (Monoid w, Monoid w', Reflex t, MonadFix m) => (w -> w') -> DynamicWriterT t w m a -> DynamicWriterT t w' m a diff --git a/src/Reflex/DynamicWriter/Class.hs b/src/Reflex/DynamicWriter/Class.hs index 1df9cf61..2df070d8 100644 --- a/src/Reflex/DynamicWriter/Class.hs +++ b/src/Reflex/DynamicWriter/Class.hs @@ -7,6 +7,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.DynamicWriter.Class ( MonadDynamicWriter , DynamicWriter(..) diff --git a/src/Reflex/EventWriter/Base.hs b/src/Reflex/EventWriter/Base.hs index 0612d66a..ed00ba38 100644 --- a/src/Reflex/EventWriter/Base.hs +++ b/src/Reflex/EventWriter/Base.hs @@ -13,6 +13,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.EventWriter.Base ( EventWriterT (..) , runEventWriterT diff --git a/src/Reflex/EventWriter/Class.hs b/src/Reflex/EventWriter/Class.hs index 41aadd35..74774b2b 100644 --- a/src/Reflex/EventWriter/Class.hs +++ b/src/Reflex/EventWriter/Class.hs @@ -6,12 +6,16 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.EventWriter.Class ( EventWriter (..) ) where import Control.Monad.Reader (ReaderT, lift) + +#if !MIN_VERSION_base(4,18,0) import Data.Semigroup (Semigroup) +#endif import Reflex.Class (Event) diff --git a/src/Reflex/FunctorMaybe.hs b/src/Reflex/FunctorMaybe.hs index 84656db5..8368562a 100644 --- a/src/Reflex/FunctorMaybe.hs +++ b/src/Reflex/FunctorMaybe.hs @@ -19,7 +19,7 @@ import Data.Map (Map) #if !MIN_VERSION_base(4,16,0) import Data.Semigroup (Option(..)) #endif -import Data.Witherable +import Witherable --TODO: See if there's a better class in the standard libraries already diff --git a/src/Reflex/Host/Class.hs b/src/Reflex/Host/Class.hs index 4f5a5b72..73044bb1 100644 --- a/src/Reflex/Host/Class.hs +++ b/src/Reflex/Host/Class.hs @@ -8,10 +8,12 @@ {-# LANGUAGE RoleAnnotations #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + -- | This module provides the interface for hosting 'Reflex' engines. This -- should only be necessary if you're writing a binding or some other library -- that provides a core event loop. diff --git a/src/Reflex/Host/Headless.hs b/src/Reflex/Host/Headless.hs index 13f66489..16d1893d 100644 --- a/src/Reflex/Host/Headless.hs +++ b/src/Reflex/Host/Headless.hs @@ -3,6 +3,7 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} module Reflex.Host.Headless where diff --git a/src/Reflex/Network.hs b/src/Reflex/Network.hs index 8f914a82..d04b2950 100644 --- a/src/Reflex/Network.hs +++ b/src/Reflex/Network.hs @@ -3,6 +3,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + -- | -- Module: -- Reflex.Network diff --git a/src/Reflex/NotReady/Class.hs b/src/Reflex/NotReady/Class.hs index 7d1232bd..5bb91a9e 100644 --- a/src/Reflex/NotReady/Class.hs +++ b/src/Reflex/NotReady/Class.hs @@ -4,10 +4,12 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.NotReady.Class ( NotReady(..) ) where diff --git a/src/Reflex/PerformEvent/Base.hs b/src/Reflex/PerformEvent/Base.hs index 9fae30ae..d961ead8 100644 --- a/src/Reflex/PerformEvent/Base.hs +++ b/src/Reflex/PerformEvent/Base.hs @@ -18,24 +18,17 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.PerformEvent.Base ( PerformEventT (..) , FireCommand (..) , hostPerformEventT ) where -import Reflex.Class -import Reflex.Adjustable.Class -import Reflex.Host.Class -import Reflex.PerformEvent.Class -import Reflex.Requester.Base -import Reflex.Requester.Class - import Control.Lens import Control.Monad.Catch (MonadMask, MonadThrow, MonadCatch) import Control.Monad.Exception import Control.Monad.Fix -import Control.Monad.Identity import Control.Monad.Primitive import Control.Monad.Reader import Control.Monad.Ref @@ -47,6 +40,17 @@ import Data.IntMap.Strict (IntMap) import qualified Data.IntMap.Strict as IntMap import qualified Data.Semigroup as S +#if !MIN_VERSION_base(4,18,0) +import Control.Monad.Identity +#endif + +import Reflex.Class +import Reflex.Adjustable.Class +import Reflex.Host.Class +import Reflex.PerformEvent.Class +import Reflex.Requester.Base +import Reflex.Requester.Class + -- | A function that fires events for the given 'EventTrigger's and then runs -- any followup actions provided via 'PerformEvent'. The given 'ReadPhase' -- action will be run once for the initial trigger execution as well as once for @@ -91,7 +95,7 @@ instance (ReflexHost t, PrimMonad (HostFrame t)) => Adjustable t (PerformEventT traverseDMapWithKeyWithAdjust f outerDm0 outerDm' = PerformEventT $ traverseDMapWithKeyWithAdjustRequesterTWith (defaultAdjustBase traversePatchDMapWithKey) mapPatchDMap weakenPatchDMapWith patchMapNewElementsMap mergeMapIncremental (\k v -> unPerformEventT $ f k v) (coerce outerDm0) (coerceEvent outerDm') traverseDMapWithKeyWithAdjustWithMove f outerDm0 outerDm' = PerformEventT $ traverseDMapWithKeyWithAdjustRequesterTWith (defaultAdjustBase traversePatchDMapWithMoveWithKey) mapPatchDMapWithMove weakenPatchDMapWithMoveWith patchMapWithMoveNewElementsMap mergeMapIncrementalWithMove (\k v -> unPerformEventT $ f k v) (coerce outerDm0) (coerceEvent outerDm') -defaultAdjustBase :: forall t v v2 k' p. (Monad (HostFrame t), PrimMonad (HostFrame t), Reflex t) +defaultAdjustBase :: forall t v v2 k' p. (Monad (HostFrame t), Reflex t) => ((forall a. k' a -> v a -> HostFrame t (v2 a)) -> p k' v -> HostFrame t (p k' v2)) -> (forall a. k' a -> v a -> HostFrame t (v2 a)) -> DMap k' v @@ -102,7 +106,7 @@ defaultAdjustBase traversePatchWithKey f' dm0 dm' = do result' <- requestingIdentity $ ffor dm' $ traversePatchWithKey f' return (result0, result') -defaultAdjustIntBase :: forall t v v2 p. (Monad (HostFrame t), PrimMonad (HostFrame t), Reflex t) +defaultAdjustIntBase :: forall t v v2 p. (Monad (HostFrame t), Reflex t) => ((IntMap.Key -> v -> HostFrame t v2) -> p v -> HostFrame t (p v2)) -> (IntMap.Key -> v -> HostFrame t v2) -> IntMap v @@ -124,9 +128,7 @@ instance ReflexHost t => MonadReflexCreateTrigger t (PerformEventT t m) where -- at the appropriate time. {-# INLINABLE hostPerformEventT #-} hostPerformEventT :: forall t m a. - ( Monad m - , MonadSubscribeEvent t m - , MonadReflexHost t m + ( MonadReflexHost t m , MonadRef m , Ref m ~ Ref IO ) diff --git a/src/Reflex/PerformEvent/Class.hs b/src/Reflex/PerformEvent/Class.hs index 1b72fdde..137e5812 100644 --- a/src/Reflex/PerformEvent/Class.hs +++ b/src/Reflex/PerformEvent/Class.hs @@ -12,18 +12,21 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.PerformEvent.Class ( PerformEvent (..) , performEventAsync ) where import Control.Monad -import Control.Monad.Fix import Control.Monad.Reader import Control.Monad.Trans.Maybe (MaybeT (..)) - import Data.Kind (Type) +#if !MIN_VERSION_base(4,18,0) +import Control.Monad.Fix +#endif + import Reflex.Class import Reflex.TriggerEvent.Class diff --git a/src/Reflex/PostBuild/Base.hs b/src/Reflex/PostBuild/Base.hs index b866c2e3..2fa326ca 100644 --- a/src/Reflex/PostBuild/Base.hs +++ b/src/Reflex/PostBuild/Base.hs @@ -13,6 +13,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.PostBuild.Base ( PostBuildT (..) , runPostBuildT @@ -21,18 +22,9 @@ module Reflex.PostBuild.Base , mapDMapWithAdjustImpl ) where -import Reflex.Class -import Reflex.Adjustable.Class -import Reflex.Host.Class -import Reflex.PerformEvent.Class -import Reflex.PostBuild.Class -import Reflex.TriggerEvent.Class - -import Control.Applicative (liftA2) import Control.Monad.Catch (MonadMask, MonadThrow, MonadCatch) import Control.Monad.Exception import Control.Monad.Fix -import Control.Monad.Identity import Control.Monad.Primitive import Control.Monad.Reader import Control.Monad.Ref @@ -44,6 +36,18 @@ import Data.IntMap.Strict (IntMap) import qualified Data.IntMap.Strict as IntMap import qualified Data.Semigroup as S +#if !MIN_VERSION_base(4,18,0) +import Control.Applicative (liftA2) +import Control.Monad.Identity +#endif + +import Reflex.Class +import Reflex.Adjustable.Class +import Reflex.Host.Class +import Reflex.PerformEvent.Class +import Reflex.PostBuild.Class +import Reflex.TriggerEvent.Class + -- | Provides a basic implementation of 'PostBuild'. newtype PostBuildT t m a = PostBuildT { unPostBuildT :: ReaderT (Event t ()) m a } deriving @@ -70,7 +74,6 @@ runPostBuildT (PostBuildT a) = runReaderT a -- TODO: Monoid and Semigroup can likely be derived once ReaderT has them. instance (Monoid a, Applicative m) => Monoid (PostBuildT t m a) where mempty = pure mempty - mappend = liftA2 mappend instance (S.Semigroup a, Applicative m) => S.Semigroup (PostBuildT t m a) where (<>) = liftA2 (S.<>) diff --git a/src/Reflex/PostBuild/Class.hs b/src/Reflex/PostBuild/Class.hs index dac1516b..d7cc9bfb 100644 --- a/src/Reflex/PostBuild/Class.hs +++ b/src/Reflex/PostBuild/Class.hs @@ -10,6 +10,7 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.PostBuild.Class ( PostBuild (..) ) where diff --git a/src/Reflex/Profiled.hs b/src/Reflex/Profiled.hs index f579df1b..cba968f5 100644 --- a/src/Reflex/Profiled.hs +++ b/src/Reflex/Profiled.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} @@ -11,6 +12,7 @@ {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE RankNTypes #-} + -- | -- Module: -- Reflex.Profiled @@ -36,7 +38,6 @@ import Data.List import Data.Kind (Type) import Data.Map (Map) import qualified Data.Map.Strict as Map -import Data.Monoid ((<>)) import Data.Ord import Data.Profunctor.Unsafe ((#.)) import qualified Data.Semigroup as S @@ -45,6 +46,12 @@ import Foreign.Ptr import GHC.Foreign import GHC.IO.Encoding import GHC.Stack +import System.IO.Unsafe + +#if !MIN_VERSION_base(4,18,0) +import Data.Monoid ((<>)) +#endif + import Reflex.Adjustable.Class import Reflex.BehaviorWriter.Class import Reflex.Class @@ -58,8 +65,6 @@ import Reflex.Query.Class import Reflex.Requester.Class import Reflex.TriggerEvent.Class -import System.IO.Unsafe - data ProfiledTimeline t {-# NOINLINE profilingData #-} diff --git a/src/Reflex/Pure.hs b/src/Reflex/Pure.hs index a0ada8ba..cd2d668c 100644 --- a/src/Reflex/Pure.hs +++ b/src/Reflex/Pure.hs @@ -5,17 +5,17 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE PolyKinds #-} - #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif - -- There are two expected orphan instances in this module: -- * MonadSample (Pure t) ((->) t) -- * MonadHold (Pure t) ((->) t) {-# OPTIONS_GHC -fno-warn-orphans #-} + -- | -- Module: Reflex.Pure -- Description: @@ -213,5 +213,5 @@ instance (Enum t, HasTrie t, Ord t) => MonadHold (Pure t) ((->) t) where headE = slowHeadE now t = Event $ guard . (t ==) - + diff --git a/src/Reflex/Query/Base.hs b/src/Reflex/Query/Base.hs index d4135e47..7f062809 100644 --- a/src/Reflex/Query/Base.hs +++ b/src/Reflex/Query/Base.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE InstanceSigs #-} @@ -19,7 +20,6 @@ module Reflex.Query.Base , mapQueryT ) where -import Control.Applicative (liftA2) import Control.Monad.Catch (MonadMask, MonadThrow, MonadCatch) import Control.Monad.Exception import Control.Monad.Fix @@ -41,12 +41,16 @@ import qualified Data.IntMap as IntMap import Data.Kind (Type) import Data.Map (Map) import qualified Data.Map as Map -import Data.Monoid ((<>)) import qualified Data.Semigroup as S import Data.Semigroup.Commutative import Data.Some (Some(Some)) import Data.These +#if !MIN_VERSION_base(4,18,0) +import Control.Applicative (liftA2) +import Data.Monoid ((<>)) +#endif + import Reflex.Class import Reflex.Adjustable.Class import Reflex.DynamicWriter.Class diff --git a/src/Reflex/Query/Class.hs b/src/Reflex/Query/Class.hs index dc6a6888..8b7b3aec 100644 --- a/src/Reflex/Query/Class.hs +++ b/src/Reflex/Query/Class.hs @@ -6,6 +6,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} + -- | -- Module: -- Reflex.Query.Class @@ -27,7 +28,6 @@ module Reflex.Query.Class , mapQueryResult ) where -import Control.Applicative import Control.Category (Category) import qualified Control.Category as Cat import Control.Monad.Reader @@ -37,12 +37,16 @@ import Data.Ix import Data.Kind (Type) import Data.Map.Monoidal (MonoidalMap) import qualified Data.Map.Monoidal as MonoidalMap -import Data.Semigroup (Semigroup(..)) import Data.Semigroup.Commutative import Data.Void import Data.Monoid hiding ((<>)) import Foreign.Storable +#if !MIN_VERSION_base(4,18,0) +import Control.Applicative +import Data.Semigroup (Semigroup(..)) +#endif + import Reflex.Class -- | A 'Query' can be thought of as a declaration of interest in some set of data. diff --git a/src/Reflex/Requester/Base/Internal.hs b/src/Reflex/Requester/Base/Internal.hs index 12d7a8f9..c8bf7cc3 100644 --- a/src/Reflex/Requester/Base/Internal.hs +++ b/src/Reflex/Requester/Base/Internal.hs @@ -19,19 +19,9 @@ #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif -module Reflex.Requester.Base.Internal where -import Reflex.Class -import Reflex.Adjustable.Class -import Reflex.Dynamic -import Reflex.EventWriter.Class -import Reflex.Host.Class -import Reflex.PerformEvent.Class -import Reflex.PostBuild.Class -import Reflex.Requester.Class -import Reflex.TriggerEvent.Class +module Reflex.Requester.Base.Internal where -import Control.Applicative (liftA2) import Control.Monad import Control.Monad.Catch (MonadMask, MonadThrow, MonadCatch) import Control.Monad.Exception @@ -55,7 +45,6 @@ import qualified Data.IntMap.Strict as IntMap import Data.Kind (Type) import Data.Map (Map) import qualified Data.Map as Map -import Data.Monoid ((<>)) import Data.Proxy import qualified Data.Semigroup as S import Data.Some (Some(Some)) @@ -65,6 +54,21 @@ import Data.Unique.Tag import GHC.Exts (Any) import Unsafe.Coerce +#if !MIN_VERSION_base(4,18,0) +import Control.Applicative (liftA2) +import Data.Monoid ((<>)) +#endif + +import Reflex.Class +import Reflex.Adjustable.Class +import Reflex.Dynamic +import Reflex.EventWriter.Class +import Reflex.Host.Class +import Reflex.PerformEvent.Class +import Reflex.PostBuild.Class +import Reflex.Requester.Class +import Reflex.TriggerEvent.Class + --TODO: Make this module type-safe newtype TagMap (f :: Type -> Type) = TagMap (IntMap Any) @@ -298,7 +302,6 @@ instance PrimMonad m => PrimMonad (RequesterT t request response m) where -- TODO: Monoid and Semigroup can likely be derived once StateT has them. instance (Monoid a, Monad m) => Monoid (RequesterT t request response m a) where mempty = pure mempty - mappend = liftA2 mappend instance (S.Semigroup a, Monad m) => S.Semigroup (RequesterT t request response m a) where (<>) = liftA2 (S.<>) diff --git a/src/Reflex/Requester/Class.hs b/src/Reflex/Requester/Class.hs index f9e50757..b0fab7ba 100644 --- a/src/Reflex/Requester/Class.hs +++ b/src/Reflex/Requester/Class.hs @@ -8,10 +8,12 @@ {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif + module Reflex.Requester.Class ( Requester (..) , withRequesting diff --git a/src/Reflex/Spider.hs b/src/Reflex/Spider.hs index 6dc64761..1236e3d6 100644 --- a/src/Reflex/Spider.hs +++ b/src/Reflex/Spider.hs @@ -1,20 +1,21 @@ {-# LANGUAGE CPP #-} + -- | -- Module: -- Reflex.Spider -- Description: -- This module exports all of the user-facing functionality of the 'Spider' 'Reflex' engine module Reflex.Spider - ( Spider - , SpiderTimeline - , Global - , SpiderHost - , runSpiderHost - , runSpiderHostForTimeline - , newSpiderTimeline - , withSpiderTimeline - -- * Deprecated - , SpiderEnv - ) where + ( Spider + , SpiderTimeline + , Global + , SpiderHost + , runSpiderHost + , runSpiderHostForTimeline + , newSpiderTimeline + , withSpiderTimeline + -- * Deprecated + , SpiderEnv + ) where import Reflex.Spider.Internal diff --git a/src/Reflex/Spider/Internal.hs b/src/Reflex/Spider/Internal.hs index bd833ed2..c7f66db9 100644 --- a/src/Reflex/Spider/Internal.hs +++ b/src/Reflex/Spider/Internal.hs @@ -20,38 +20,35 @@ {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE InstanceSigs #-} {-# LANGUAGE MultiWayIf #-} - #ifdef USE_REFLEX_OPTIMIZER {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif {-# OPTIONS_GHC -Wunused-binds #-} + -- | This module is the implementation of the 'Spider' 'Reflex' engine. It uses -- a graph traversal algorithm to propagate 'Event's and 'Behavior's. -module Reflex.Spider.Internal (module Reflex.Spider.Internal) where +module Reflex.Spider.Internal + ( module Reflex.Spider.Internal + ) where -#if MIN_VERSION_base(4,10,0) -import Control.Applicative (liftA2) -#endif import Control.Concurrent import Control.Exception import Control.Monad hiding (forM, forM_, mapM, mapM_) import Control.Monad.Catch (MonadMask, MonadThrow, MonadCatch) import Control.Monad.Exception import Control.Monad.Fix -import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_) import Control.Monad.Primitive import Control.Monad.Reader.Class import Control.Monad.IO.Class import Control.Monad.ReaderIO import Control.Monad.Ref -import Control.Monad.Fail (MonadFail) import qualified Control.Monad.Fail as MonadFail import Data.Align import Data.Coerce import Data.Dependent.Map (DMap) import qualified Data.Dependent.Map as DMap import Data.Dependent.Sum (DSum (..)) -import Data.FastMutableIntMap (FastMutableIntMap, PatchIntMap (..)) +import Data.FastMutableIntMap (FastMutableIntMap) import qualified Data.FastMutableIntMap as FastMutableIntMap import Data.Foldable hiding (concat, elem, sequence_) import Data.Functor.Constant @@ -63,12 +60,10 @@ import qualified Data.IntMap.Strict as IntMap import Data.IORef import Data.Kind (Type) import Data.Maybe hiding (mapMaybe) -import Data.Monoid (mempty, (<>)) import Data.Proxy import Data.These import Data.Traversable import Data.Type.Equality ((:~:)(Refl)) -import Data.Witherable (Filterable, mapMaybe) import GHC.Exts hiding (toList) import GHC.IORef (IORef (..)) import GHC.Stack @@ -76,6 +71,18 @@ import Reflex.FastWeak import System.IO.Unsafe import System.Mem.Weak import Unsafe.Coerce +import Witherable (Filterable, mapMaybe) + +#if !MIN_VERSION_base(4,18,0) +import Control.Applicative (liftA2) +import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_) +import Control.Monad.Fail (MonadFail) +import Data.FastMutableIntMap (PatchIntMap (..)) +import Data.List (isPrefixOf) +import Data.Monoid (mempty, (<>)) +#else +import Control.Monad.Identity +#endif #ifdef MIN_VERSION_semialign #if MIN_VERSION_these(0,8,0) @@ -93,7 +100,6 @@ import Control.Monad.State hiding (forM, forM_, mapM, mapM_, sequence) import Data.List.NonEmpty (NonEmpty (..), nonEmpty) import qualified Data.List.NonEmpty as NonEmpty import Data.Tree (Forest, Tree (..), drawForest) -import Data.List (isPrefixOf) import Data.FastWeakBag (FastWeakBag, FastWeakBagTicket) import qualified Data.FastWeakBag as FastWeakBag @@ -253,7 +259,7 @@ subscribeAndRead = unEvent -- caching; if the computation function is very cheap, this is (much) more -- efficient than 'push' {-# INLINE [1] pushCheap #-} -pushCheap :: HasSpiderTimeline x => (a -> ComputeM x (Maybe b)) -> Event x a -> Event x b +pushCheap :: (a -> ComputeM x (Maybe b)) -> Event x a -> Event x b pushCheap !f e = Event $ \sub -> do (subscription, occ) <- subscribeAndRead e $ debugSubscriber' "push" $ sub { subscriberPropagate = \a -> do @@ -274,7 +280,7 @@ terminalSubscriber p = Subscriber -- | Subscribe to an Event only for the duration of one occurrence {-# INLINE subscribeAndReadHead #-} -subscribeAndReadHead :: HasSpiderTimeline x => Event x a -> Subscriber x a -> EventM x (EventSubscription x, Maybe a) +subscribeAndReadHead :: Event x a -> Subscriber x a -> EventM x (EventSubscription x, Maybe a) subscribeAndReadHead e sub = do subscriptionRef <- liftIO $ newIORef $ error "subscribeAndReadHead: not initialized" (subscription, occ) <- subscribeAndRead e $ debugSubscriber' "head" $ sub @@ -288,7 +294,7 @@ subscribeAndReadHead e sub = do return (subscription, occ) --TODO: Make this lazy in its input event -headE :: (MonadIO m, Defer (SomeMergeInit x) m, HasSpiderTimeline x) => Event x a -> m (Event x a) +headE :: Defer (SomeMergeInit x) m => Event x a -> m (Event x a) headE originalE = do parent <- liftIO $ newIORef $ Just originalE defer $ SomeMergeInit $ do --TODO: Rename SomeMergeInit appropriately @@ -309,12 +315,10 @@ data CacheSubscribed x a #endif } -nowSpiderEventM :: (HasSpiderTimeline x) => EventM x (R.Event (SpiderTimeline x) ()) -nowSpiderEventM = - SpiderEvent <$> now +nowSpiderEventM :: HasSpiderTimeline x => EventM x (R.Event (SpiderTimeline x) ()) +nowSpiderEventM = SpiderEvent <$> now -now :: (MonadIO m, Defer (Some Clear) m, HasSpiderTimeline x - ) => m (Event x ()) +now :: Defer (Some Clear) m => m (Event x ()) now = do nowOrNot <- liftIO $ newIORef $ Just () scheduleClear nowOrNot @@ -553,14 +557,14 @@ recalculateSubscriberHeight :: Height -> Subscriber x a -> IO () recalculateSubscriberHeight = flip subscriberRecalculateHeight -- | Propagate everything at the current height -propagate :: forall x a. HasSpiderTimeline x => a -> WeakBag (Subscriber x a) -> EventM x () +propagate :: a -> WeakBag (Subscriber x a) -> EventM x () propagate a subscribers = withIncreasedDepth (Proxy::Proxy x) $ -- Note: in the following traversal, we do not visit nodes that are added to the list during our traversal; they are new events, which will necessarily have full information already, so there is no need to traverse them --TODO: Should we check if nodes already have their values before propagating? Maybe we're re-doing work WeakBag.traverse_ subscribers $ \s -> subscriberPropagate s a -- | Propagate everything at the current height -propagateFast :: forall x a. HasSpiderTimeline x => a -> FastWeakBag (Subscriber x a) -> EventM x () +propagateFast :: a -> FastWeakBag (Subscriber x a) -> EventM x () propagateFast a subscribers = withIncreasedDepth (Proxy::Proxy x) $ -- Note: in the following traversal, we do not visit nodes that are added to the list during our traversal; they are new events, which will necessarily have full information already, so there is no need to traverse them --TODO: Should we check if nodes already have their values before propagating? Maybe we're re-doing work @@ -993,9 +997,9 @@ instance Monad (BehaviorM x) where {-# INLINE (>>=) #-} BehaviorM x >>= f = BehaviorM $ x >>= unBehaviorM . f {-# INLINE (>>) #-} - BehaviorM x >> BehaviorM y = BehaviorM $ x >> y + (>>) = (*>) {-# INLINE return #-} - return x = BehaviorM $ return x + return = pure #if !MIN_VERSION_base(4,13,0) {-# INLINE fail #-} fail s = BehaviorM $ fail s @@ -1096,7 +1100,7 @@ heightBagRemove (Height h) b@(HeightBag s c) = heightBagVerify $ case IntMap.loo _ -> IntMap.insert h (pred old) c heightBagRemoveMaybe :: Height -> HeightBag -> Maybe HeightBag -heightBagRemoveMaybe (Height h) b@(HeightBag s c) = heightBagVerify . removed <$> IntMap.lookup h c where +heightBagRemoveMaybe (Height h) (HeightBag s c) = heightBagVerify . removed <$> IntMap.lookup h c where removed old = HeightBag (pred s) $ case old of 0 -> IntMap.delete h c _ -> IntMap.insert h (pred old) c @@ -1473,7 +1477,7 @@ filterStack :: String -> [String] -> [String] #ifdef DEBUG_HIDE_INTERNALS filterStack prefix = filter (not . (prefix `isPrefixOf`)) #else -filterStack prefix = id +filterStack _ = id #endif #ifdef DEBUG_CYCLES @@ -2055,7 +2059,7 @@ scheduleMergeSelf m height = scheduleMerge' height (_merge_heightRef m) $ do --TODO: Assert that m is not empty subscriberPropagate (_merge_sub m) vals -checkCycle :: HasSpiderTimeline x => EventSubscribed x -> EventM x () +checkCycle :: EventSubscribed x -> EventM x () checkCycle subscribed = liftIO $ do height <- readIORef (eventSubscribedHeightRef subscribed) @@ -2109,7 +2113,7 @@ updateMerge subscribed m updateFunc p = SomeMergeUpdate updateMe (invalidateMerg {-# INLINE mergeGCheap' #-} mergeGCheap' :: forall k v x p s q. (HasSpiderTimeline x, GCompare k, PatchTarget p ~ DMap k q) => MergeGetSubscription x s -> MergeInitFunc k v q x s -> MergeUpdateFunc k v x p s -> MergeDestroyFunc k s -> DynamicS x p -> Event x (DMap k v) -mergeGCheap' getParent getInitialSubscribers updateFunc destroy d = Event $ \sub -> do +mergeGCheap' _ getInitialSubscribers updateFunc destroy d = Event $ \sub -> do initialParents <- readBehaviorUntracked $ dynamicCurrent d accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized" heightRef <- liftIO $ newIORef $ error "merge: heightRef not yet initialized" @@ -2614,7 +2618,7 @@ instance HasSpiderTimeline x => Reflex.Class.MonadHold (SpiderTimeline x) (Spide headE e = runFrame . runSpiderHostFrame $ Reflex.Class.headE e {-# INLINABLE now #-} now = runFrame . runSpiderHostFrame $ Reflex.Class.now - + instance HasSpiderTimeline x => Reflex.Class.MonadSample (SpiderTimeline x) (SpiderHostFrame x) where sample = SpiderHostFrame . readBehaviorUntracked . unSpiderBehavior --TODO: This can cause problems with laziness, so we should get rid of it if we can @@ -2843,9 +2847,9 @@ instance Monad (SpiderHost x) where {-# INLINABLE (>>=) #-} SpiderHost x >>= f = SpiderHost $ x >>= unSpiderHost . f {-# INLINABLE (>>) #-} - SpiderHost x >> SpiderHost y = SpiderHost $ x >> y + (>>) = (*>) {-# INLINABLE return #-} - return x = SpiderHost $ return x + return = pure #if !MIN_VERSION_base(4,13,0) {-# INLINABLE fail #-} fail = MonadFail.fail @@ -2872,9 +2876,9 @@ instance Monad (SpiderHostFrame x) where {-# INLINABLE (>>=) #-} SpiderHostFrame x >>= f = SpiderHostFrame $ x >>= runSpiderHostFrame . f {-# INLINABLE (>>) #-} - SpiderHostFrame x >> SpiderHostFrame y = SpiderHostFrame $ x >> y + (>>) = (*>) {-# INLINABLE return #-} - return x = SpiderHostFrame $ return x + return = pure #if !MIN_VERSION_base(4,13,0) {-# INLINABLE fail #-} fail s = SpiderHostFrame $ fail s diff --git a/src/Reflex/Time.hs b/src/Reflex/Time.hs index 4ae42f26..bed11200 100644 --- a/src/Reflex/Time.hs +++ b/src/Reflex/Time.hs @@ -11,6 +11,7 @@ #ifdef USE_TEMPLATE_HASKELL {-# LANGUAGE TemplateHaskell #-} #endif + -- | -- Module: -- Reflex.Time @@ -18,12 +19,6 @@ -- Clocks, timers, and other time-related functions. module Reflex.Time where -import Reflex.Class -import Reflex.Dynamic -import Reflex.PerformEvent.Class -import Reflex.PostBuild.Class -import Reflex.TriggerEvent.Class - import Control.Concurrent import qualified Control.Concurrent.Thread.Delay as Concurrent import Control.Lens hiding ((|>)) @@ -33,7 +28,6 @@ import Control.Monad.IO.Class import Data.Align import Data.Data (Data) import Data.Fixed -import Data.Semigroup (Semigroup(..)) import Data.Sequence (Seq, (|>)) import qualified Data.Sequence as Seq import Data.These @@ -42,6 +36,16 @@ import Data.Typeable import GHC.Generics (Generic) import System.Random +#if !MIN_VERSION_base(4,18,0) +import Data.Semigroup (Semigroup(..)) +#endif + +import Reflex.Class +import Reflex.Dynamic +import Reflex.PerformEvent.Class +import Reflex.PostBuild.Class +import Reflex.TriggerEvent.Class + -- | Metadata associated with a timer "tick" data TickInfo = TickInfo { _tickInfo_lastUTC :: UTCTime diff --git a/src/Reflex/TriggerEvent/Base.hs b/src/Reflex/TriggerEvent/Base.hs index 2e409447..7d4de55c 100644 --- a/src/Reflex/TriggerEvent/Base.hs +++ b/src/Reflex/TriggerEvent/Base.hs @@ -1,10 +1,13 @@ -- | This module defines 'TriggerEventT', the standard implementation of -- 'TriggerEvent'. +{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} + module Reflex.TriggerEvent.Base ( TriggerEventT (..) , runTriggerEventT @@ -13,7 +16,6 @@ module Reflex.TriggerEvent.Base , EventTriggerRef (..) ) where -import Control.Applicative (liftA2) import Control.Concurrent import Control.Monad.Catch (MonadMask, MonadThrow, MonadCatch) import Control.Monad.Exception @@ -24,8 +26,13 @@ import Control.Monad.Ref import Data.Coerce import Data.Dependent.Sum import Data.IORef -import Data.Monoid ((<>)) import qualified Data.Semigroup as S + +#if !MIN_VERSION_base(4,18,0) +import Control.Applicative (liftA2) +import Data.Monoid ((<>)) +#endif + import Reflex.Class import Reflex.Adjustable.Class import Reflex.Host.Class diff --git a/src/Reflex/TriggerEvent/Class.hs b/src/Reflex/TriggerEvent/Class.hs index f747db12..0589a1fe 100644 --- a/src/Reflex/TriggerEvent/Class.hs +++ b/src/Reflex/TriggerEvent/Class.hs @@ -3,6 +3,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE UndecidableInstances #-} + module Reflex.TriggerEvent.Class ( TriggerEvent (..) ) where diff --git a/src/Reflex/Workflow.hs b/src/Reflex/Workflow.hs index 71317a1e..0efc4eea 100644 --- a/src/Reflex/Workflow.hs +++ b/src/Reflex/Workflow.hs @@ -1,5 +1,6 @@ {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE ScopedTypeVariables #-} + -- | -- Module: -- Reflex.Workflow @@ -7,8 +8,8 @@ -- Provides a convenient way to describe a series of interrelated widgets that -- can send data to, invoke, and replace one another. Useful for modeling user interface -- "workflows." -module Reflex.Workflow ( - Workflow (..) +module Reflex.Workflow + ( Workflow (..) , workflow , workflowView , mapWorkflow @@ -30,13 +31,13 @@ import Reflex.PostBuild.Class newtype Workflow t m a = Workflow { unWorkflow :: m (a, Event t (Workflow t m a)) } -- | Runs a 'Workflow' and returns the 'Dynamic' result of the 'Workflow' (i.e., a 'Dynamic' of the value produced by the current 'Workflow' node, and whose update 'Event' fires whenever one 'Workflow' is replaced by another). -workflow :: forall t m a. (Reflex t, Adjustable t m, MonadFix m, MonadHold t m) => Workflow t m a -> m (Dynamic t a) +workflow :: forall t m a. (Adjustable t m, MonadFix m, MonadHold t m) => Workflow t m a -> m (Dynamic t a) workflow w0 = do rec eResult <- networkHold (unWorkflow w0) $ fmap unWorkflow $ switch $ snd <$> current eResult return $ fmap fst eResult -- | Similar to 'workflow', but outputs an 'Event' that fires at post-build time and whenever the current 'Workflow' is replaced by the next 'Workflow'. -workflowView :: forall t m a. (Reflex t, NotReady t m, Adjustable t m, MonadFix m, MonadHold t m, PostBuild t m) => Workflow t m a -> m (Event t a) +workflowView :: forall t m a. (NotReady t m, Adjustable t m, MonadFix m, MonadHold t m, PostBuild t m) => Workflow t m a -> m (Event t a) workflowView w0 = do rec eResult <- networkView . fmap unWorkflow =<< holdDyn w0 eReplace eReplace <- fmap switch $ hold never $ fmap snd eResult diff --git a/test/DebugCycles.hs b/test/DebugCycles.hs index e0bf3f67..e42d6d25 100644 --- a/test/DebugCycles.hs +++ b/test/DebugCycles.hs @@ -29,7 +29,7 @@ import Reflex.EventWriter.Base import Test.Run import Test.Hspec import Reflex.Spider.Internal (EventLoopException) -import Data.Witherable (Filterable) +import Witherable (Filterable) #if defined(MIN_VERSION_these_lens) || (MIN_VERSION_these(0,8,0) && !MIN_VERSION_these(0,9,0)) import Data.These.Lens