4synopsis: Beautiful Streaming, Concurrent and Reactive Composition
6 Streamly is a framework for writing programs in a high level, declarative
7 data flow programming paradigm. It provides a simple API, very close to
8 standard Haskell lists. A program is expressed as a composition of data
9 processing pipes, generally known as streams. Streams can be generated,
10 merged, chained, mapped, zipped, and consumed concurrently – enabling a high
11 level, declarative yet concurrent composition of programs. Programs can be
12 concurrent or non-concurrent without any significant change. Concurrency is
13 auto scaled based on consumption rate. Programmers do not have to be aware
14 of threads, locking or synchronization to write scalable concurrent programs.
15 Streamly provides C like performance, orders of magnitude better compared to
16 existing streaming libraries.
18 Streamly is designed to express the full spectrum of programs with highest
19 performance. Do not think that if you are writing a small and simple program
20 it may not be for you. It expresses a small "hello world" program with the
21 same efficiency, simplicity and elegance as a large scale concurrent
22 application. It unifies many different aspects of special purpose libraries
23 into a single yet simple framework.
25 Streamly covers the functionality provided by Haskell lists as well as the
26 functionality provided by streaming libraries like
27 <https://hackage.haskell.org/package/streaming streaming>,
28 <https://hackage.haskell.org/package/pipes pipes>, and
29 <https://hackage.haskell.org/package/conduit conduit> with a simpler API and
30 better performance. Streamly provides
31 advanced stream composition including various ways of appending, merging,
32 zipping, splitting, grouping, distributing, partitioning and unzipping of
33 streams with true streaming and with concurrency. Streamly subsumes the
34 functionality of list transformer libraries like @pipes@ or
35 <https://hackage.haskell.org/package/list-t list-t> and also the logic
36 programming library <https://hackage.haskell.org/package/logict logict>.
37 The grouping, splitting and windowing combinators in streamly can be compared
38 to the window operators in <https://flink.apache.org/ Apache Flink>.
39 However, compared to Flink streamly has a pure functional, succinct and
42 The concurrency capabilities of streamly are much more advanced and powerful
43 compared to the basic concurrency functionality provided by the
44 <https://hackage.haskell.org/package/async async> package. Streamly is a
45 first class reactive programming library. If you are familiar with
46 <http://reactivex.io/ Reactive Extensions> you will find that it is very
47 similar. For most RxJs combinators you can find or write corresponding ones
48 in streamly. Streamly can be used as an alternative to
49 <https://hackage.haskell.org/package/Yampa Yampa> or
50 <https://hackage.haskell.org/package/reflex reflex> as well.
52 Streamly focuses on practical engineering with high performance. From well
53 written streamly programs one can expect performance competitive to C. High
54 performance streaming eliminates the need for string and text libraries like
55 <https://hackage.haskell.org/package/bytestring bytestring>,
56 <https://hackage.haskell.org/package/text text> and their lazy and strict
57 flavors. The confusion and cognitive overhead arising from different
58 string types is eliminated. The two fundamental types in streamly are arrays
59 for storage and streams for processing. Strings and text are simply streams
60 or arrays of 'Char' as they should be. Arrays in streamly have performance
61 at par with the vector library.
63 Where to find more information:
65 * /Quick Overview/: <#readme README file> in the package
66 * /Building/: <src/docs/Build.md Build guide> for optimal performance
67 * /Detailed Tutorial/: "Streamly.Tutorial" module in the haddock documentation
68 * /Interoperation/: "Streamly.Tutorial" module for interop with other
70 * /Reference Documentation/: Haddock documentation for the respective modules
71 * /Examples/: <src/examples examples directory> in the package
72 * /Guides/: <src/docs docs directory> in the package, for documentation on
73 advanced topics, limitations, semantics of the library or on specific use
75 * <https://github.com/composewell/streaming-benchmarks Streaming Benchmarks>
76 * <https://github.com/composewell/concurrency-benchmarks Concurrency Benchmarks>
80homepage: https://github.com/composewell/streamly
81bug-reports: https://github.com/composewell/streamly/issues
84tested-with: GHC==8.0.2
90maintainer: streamly@composewell.com
91copyright: 2017 Harendra Kumar
92category: Control, Concurrency, Streaming, Reactivity
93stability: Experimental
98 .github/workflows/haskell.yml
112 benchmark/Streamly/Benchmark/Data/*.hs
113 benchmark/Streamly/Benchmark/Data/Parser/*.hs
114 benchmark/Streamly/Benchmark/Data/Stream/*.hs
115 benchmark/Streamly/Benchmark/FileSystem/*.hs
116 benchmark/Streamly/Benchmark/FileSystem/Handle/*.hs
117 benchmark/Streamly/Benchmark/Prelude/*.hs
118 benchmark/lib/Streamly/Benchmark/*.hs
119 benchmark/streamly-benchmarks.cabal
120 bin/bench-exec-one.sh
122 charts-0/streamly-vs-list-time.svg
126 credits/Yampa-0.10.6.2.txt
127 credits/base-4.12.0.0.txt
128 credits/bjoern-2008-2009.txt
129 credits/clock-0.7.2.txt
130 credits/foldl-1.4.5.txt
131 credits/pipes-concurrency-2.0.8.txt
132 credits/primitive-0.7.0.0.txt
133 credits/transient-0.5.5.txt
134 credits/vector-0.12.0.2.txt
139 docs/streamly-vs-async.md
140 docs/streamly-vs-lists.md
143 src/Streamly/Internal/Data/Stream/Instances.hs
144 src/Streamly/Internal/Data/Time/config-clock.h
145 src/Streamly/Internal/Data/Array/PrimInclude.hs
146 src/Streamly/Internal/Data/Array/Prim/TypesInclude.hs
147 src/Streamly/Internal/Data/Array/Prim/MutTypesInclude.hs
148 src/Streamly/Internal/Data/Time/config.h.in
156 src/Streamly/Internal/Data/Time/config.h
158source-repository head
160 location: https://github.com/composewell/streamly
163 description: Use fusion plugin for benchmarks and executables
168 description: Enable inspection testing
173 description: Debug build with asserts enabled
178 description: Development build
183 description: Use llvm backend for code generation
188 description: Disable rewrite rules for stream fusion
193 description: Use CPS style streams when possible
198 description: Build including examples
203 description: Build including SDL examples
208 description: Use C malloc instead of GHC malloc
212-------------------------------------------------------------------------------
214-------------------------------------------------------------------------------
216common compile-options
217 default-language: Haskell2010
219 cpp-options: -DUSE_STREAMK_ONLY
222 cpp-options: -DDISABLE_FUSION
225 cpp-options: -DDEVBUILD
228 cpp-options: -DINSPECTION
230 if flag(use-c-malloc)
231 cpp-options: -DUSE_C_MALLOC
235 -Wunrecognised-warning-flags
237 -Wincomplete-record-updates
238 -Wincomplete-uni-patterns
239 -Wredundant-constraints
240 -Wnoncanonical-monad-instances
246 ghc-options: -Wmissed-specialisations
247 -Wall-missed-specialisations
249 if flag(dev) || flag(debug)
250 ghc-options: -fno-ignore-asserts
252common default-extensions
261 ExistentialQuantification
264 GeneralizedNewtypeDeriving
269 MultiParamTypeClasses
278 -- MonoLocalBinds, enabled by TypeFamilies, causes performance
279 -- regressions. Disable it. This must come after TypeFamilies,
280 -- otherwise TypeFamilies will enable it again.
283 -- UndecidableInstances -- Does not show any perf impact
284 -- UnboxedTuples -- interferes with (#.)
286common optimization-options
289 -fspec-constr-recursive=16
292common threading-options
293 ghc-options: -threaded
296-- We need optimization options here to optimize internal (non-inlined)
297-- versions of functions. Also, we have some benchmarking inspection tests
298-- part of the library when built with --benchmarks flag. Thos tests fail
299-- if we do not use optimization options here. It was observed that due to
300-- -O2 here some concurrent/nested benchmarks improved and others regressed.
301-- We can investigate a bit more here why the regression occurred.
303 import: compile-options, optimization-options, default-extensions
305-- Compilation for coverage builds on CI machines takes too long without -O0
306-- XXX we should use coverage flag for that, -O0 may take too long to run tests
309 import: compile-options, threading-options, default-extensions
313 -- XXX we need -O for plugin to work
314 -- if flag(fusion-plugin) && !impl(ghcjs) && !impl(ghc < 8.6)
315 -- ghc-options: -fplugin Fusion.Plugin
317 -- fusion-plugin >= 0.2 && < 0.3
319common prelude-test-options
320 js-sources: jsbits/clock.js
325 , QuickCheck >= 2.10 && < 2.15
326 , hspec >= 2.0 && < 3
327 default-language: Haskell2010
329-- Used by maxrate test, benchmarks and executables
331 import: compile-options, optimization-options, threading-options
332 if flag(fusion-plugin) && !impl(ghcjs) && !impl(ghc < 8.6)
333 ghc-options: -fplugin Fusion.Plugin
335 fusion-plugin >= 0.2 && < 0.3
337-------------------------------------------------------------------------------
339-------------------------------------------------------------------------------
345 default-extensions: TypeApplications
347 default-extensions: QuantifiedConstraints
349 js-sources: jsbits/clock.js
350 include-dirs: src/Streamly/Internal/Data/Time
353 c-sources: src/Streamly/Internal/Data/Time/Windows.c
355 c-sources: src/Streamly/Internal/Data/Time/Darwin.c
359 , Streamly.Data.Prim.Array
360 , Streamly.Data.SmallArray
363 , Streamly.Memory.Ring
365 , Streamly.FileSystem.IOVec
366 , Streamly.FileSystem.FDIO
367 , Streamly.FileSystem.FD
373 , Streamly.Data.Unfold
374 , Streamly.Data.Unicode.Stream
377 , Streamly.Memory.Array
378 , Streamly.FileSystem.Handle
383 , Streamly.Internal.BaseCompat
384 , Streamly.Internal.Control.Monad
385 , Streamly.Internal.Data.Tuple.Strict
386 , Streamly.Internal.Data.Maybe.Strict
387 , Streamly.Internal.Data.Either.Strict
388 , Streamly.Internal.Data.Atomics
389 , Streamly.Internal.Data.Time
390 , Streamly.Internal.Data.Time.TimeSpec
391 , Streamly.Internal.Data.Time.Units
392 , Streamly.Internal.Data.Time.Clock
393 , Streamly.Internal.Data.SVar
396 , Streamly.Internal.Foreign.Malloc
399 , Streamly.Internal.Data.IORef.Prim
402 , Streamly.Internal.Data.Array
403 , Streamly.Internal.Data.Array.Prim.Types
404 , Streamly.Internal.Data.Array.Prim
405 , Streamly.Internal.Data.Array.Prim.Mut.Types
406 , Streamly.Internal.Data.Array.Prim.Pinned.Types
407 , Streamly.Internal.Data.Array.Prim.Pinned
408 , Streamly.Internal.Data.Array.Prim.Pinned.Mut.Types
409 , Streamly.Internal.Data.SmallArray.Types
410 , Streamly.Internal.Data.SmallArray
411 , Streamly.Internal.Memory.Mutable.Array.Types
412 , Streamly.Internal.Memory.Array.Types
413 , Streamly.Internal.Memory.Array
414 , Streamly.Internal.Memory.ArrayStream
417 , Streamly.Internal.Data.Fold.Types
418 , Streamly.Internal.Data.Fold
419 , Streamly.Internal.Data.Sink.Types
420 , Streamly.Internal.Data.Sink
423 , Streamly.Internal.Data.Parser.ParserK.Types
424 , Streamly.Internal.Data.Parser.ParserD.Types
425 , Streamly.Internal.Data.Parser.ParserD.Tee
426 , Streamly.Internal.Data.Parser.ParserD
427 , Streamly.Internal.Data.Parser
430 , Streamly.Internal.Data.Stream.StreamK.Type
431 , Streamly.Internal.Data.Stream.StreamK
432 , Streamly.Internal.Data.Stream.StreamD.Type
433 , Streamly.Internal.Data.Stream.StreamD
434 , Streamly.Internal.Data.Stream.StreamDK.Type
435 , Streamly.Internal.Data.Stream.StreamDK
436 , Streamly.Internal.Data.Stream.Enumeration
437 , Streamly.Internal.Data.Stream.Prelude
439 -- Higher level streams
440 , Streamly.Internal.Data.Stream.IsStream
441 , Streamly.Internal.Data.Stream.SVar
442 , Streamly.Internal.Data.Stream.Serial
443 , Streamly.Internal.Data.Stream.Async
444 , Streamly.Internal.Data.Stream.Parallel
445 , Streamly.Internal.Data.Stream.Ahead
446 , Streamly.Internal.Data.Stream.Zip
447 , Streamly.Internal.Data.Stream.Combinators
448 , Streamly.Internal.Data.List
451 , Streamly.Internal.Data.Unfold.Types
452 , Streamly.Internal.Data.Unfold
455 , Streamly.Internal.Data.Pipe.Types
456 , Streamly.Internal.Data.Pipe
459 , Streamly.Internal.FileSystem.Handle
460 , Streamly.Internal.FileSystem.Dir
461 , Streamly.Internal.FileSystem.File
464 , Streamly.Internal.Data.Unicode.Stream
465 , Streamly.Internal.Data.Unicode.Char
466 , Streamly.Internal.Memory.Unicode.Array
467 , Streamly.Internal.Unicode.Array.Prim.Pinned
469 -- Serialization/deserialization in binary format
470 , Streamly.Internal.Data.Binary.Decode
474 Streamly.Network.Socket
475 , Streamly.Network.Inet.TCP
477 , Streamly.Internal.Network.Socket
478 , Streamly.Internal.Network.Inet.TCP
481 -- Core libraries shipped with ghc, the min and max
482 -- constraints of these libraries should match with
483 -- the GHC versions we support
485 , containers >= 0.5 && < 0.7
486 , deepseq >= 1.4.1 && < 1.5
487 , directory >= 1.2.2 && < 1.4
488 , exceptions >= 0.8 && < 0.11
489 , ghc-prim >= 0.2 && < 0.7
491 , primitive >= 0.5.4 && < 0.8
492 , transformers >= 0.4 && < 0.6
494 , heaps >= 0.3 && < 0.4
497 , atomic-primops >= 0.8 && < 0.9
498 , lockfree-queue >= 0.2.3 && < 0.3
501 , monad-control >= 1.0 && < 2
502 , transformers-base >= 0.4 && < 0.5
504 , fusion-plugin-types >= 0.1 && < 0.2
508 network >= 2.6 && < 4
511 build-depends: template-haskell >= 2.14 && < 2.17
512 , inspection-testing >= 0.4 && < 0.5
514 -- Array uses a Storable constraint in dev build making several inspection
516 if flag(dev) && flag(inspection)
517 build-depends: inspection-and-dev-flags-cannot-be-used-together
519-------------------------------------------------------------------------------
521-------------------------------------------------------------------------------
525 type: exitcode-stdio-1.0
527 js-sources: jsbits/clock.js
532 , hspec >= 2.0 && < 3
533 , containers >= 0.5 && < 0.7
534 , transformers >= 0.4 && < 0.6
536 , exceptions >= 0.8 && < 0.11
537 default-language: Haskell2010
539test-suite internal-prelude-test
541 type: exitcode-stdio-1.0
542 main-is: Streamly/Test/Internal/Prelude.hs
543 js-sources: jsbits/clock.js
548 , QuickCheck >= 2.10 && < 2.15
549 , hspec >= 2.0 && < 3
550 default-language: Haskell2010
552test-suite pure-streams-base
554 type: exitcode-stdio-1.0
555 main-is: PureStreams.hs
560 , hspec >= 2.0 && < 3
561 default-language: Haskell2010
563test-suite pure-streams-streamly
565 type: exitcode-stdio-1.0
566 main-is: PureStreams.hs
568 cpp-options: -DUSE_STREAMLY_LIST
572 , hspec >= 2.0 && < 3
573 default-language: Haskell2010
575test-suite Prelude.Serial
576 import: test-options, prelude-test-options
577 type: exitcode-stdio-1.0
578 main-is: Streamly/Test/Prelude/Serial.hs
579 ghc-options: -main-is Streamly.Test.Prelude.Serial.main
580 other-modules: Streamly.Test.Common
581 , Streamly.Test.Prelude
583test-suite Prelude.WSerial
584 import: test-options, prelude-test-options
585 type: exitcode-stdio-1.0
586 main-is: Streamly/Test/Prelude/WSerial.hs
587 ghc-options: -main-is Streamly.Test.Prelude.WSerial.main
588 other-modules: Streamly.Test.Common
589 , Streamly.Test.Prelude
591test-suite Prelude.ZipSerial
592 import: test-options, prelude-test-options
593 type: exitcode-stdio-1.0
594 main-is: Streamly/Test/Prelude/ZipSerial.hs
595 ghc-options: -main-is Streamly.Test.Prelude.ZipSerial.main
596 other-modules: Streamly.Test.Common
597 , Streamly.Test.Prelude
599test-suite Prelude.ZipAsync
600 import: test-options, prelude-test-options
601 type: exitcode-stdio-1.0
602 main-is: Streamly/Test/Prelude/ZipAsync.hs
603 ghc-options: -main-is Streamly.Test.Prelude.ZipAsync.main
604 other-modules: Streamly.Test.Common
605 , Streamly.Test.Prelude
607test-suite Prelude.Ahead
608 import: test-options, prelude-test-options
609 type: exitcode-stdio-1.0
610 main-is: Streamly/Test/Prelude/Ahead.hs
611 ghc-options: -main-is Streamly.Test.Prelude.Ahead.main
612 other-modules: Streamly.Test.Common
613 , Streamly.Test.Prelude
615test-suite Prelude.Async
616 import: test-options, prelude-test-options
617 type: exitcode-stdio-1.0
618 main-is: Streamly/Test/Prelude/Async.hs
619 ghc-options: -main-is Streamly.Test.Prelude.Async.main
620 other-modules: Streamly.Test.Common
621 , Streamly.Test.Prelude
623test-suite Prelude.WAsync
624 import: test-options, prelude-test-options
625 type: exitcode-stdio-1.0
626 main-is: Streamly/Test/Prelude/WAsync.hs
627 ghc-options: -main-is Streamly.Test.Prelude.WAsync.main
628 other-modules: Streamly.Test.Common
629 , Streamly.Test.Prelude
631test-suite Prelude.Parallel
632 import: test-options, prelude-test-options
633 type: exitcode-stdio-1.0
634 main-is: Streamly/Test/Prelude/Parallel.hs
635 ghc-options: -main-is Streamly.Test.Prelude.Parallel.main
636 other-modules: Streamly.Test.Common
637 , Streamly.Test.Prelude
639test-suite Prelude.Concurrent
640 import: test-options, prelude-test-options
641 type: exitcode-stdio-1.0
642 main-is: Streamly/Test/Prelude/Concurrent.hs
643 ghc-options: -main-is Streamly.Test.Prelude.Concurrent.main
644 other-modules: Streamly.Test.Common
645 , Streamly.Test.Prelude
649 type: exitcode-stdio-1.0
650 main-is: Streamly/Test/Array.hs
651 js-sources: jsbits/clock.js
653 cpp-options: -DTEST_ARRAY
657 , QuickCheck >= 2.10 && < 2.15
658 , hspec >= 2.0 && < 3
659 default-language: Haskell2010
661test-suite internal-data-fold-test
663 type: exitcode-stdio-1.0
664 main-is: Streamly/Test/Internal/Data/Fold.hs
665 js-sources: jsbits/clock.js
670 , hspec >= 2.0 && < 3
671 , QuickCheck >= 2.10 && < 2.15
672 default-language: Haskell2010
674test-suite internal-data-parser-test
677 type: exitcode-stdio-1.0
678 main-is: Streamly/Test/Internal/Data/Parser.hs
679 js-sources: jsbits/clock.js
684 , hspec >= 2.0 && < 3
685 , QuickCheck >= 2.10 && < 2.15
686 , transformers >= 0.4 && < 0.6
687 default-language: Haskell2010
689test-suite internal-data-parser-parserd-test
691 type: exitcode-stdio-1.0
692 main-is: Streamly/Test/Internal/Data/Parser/ParserD.hs
693 js-sources: jsbits/clock.js
698 , hspec >= 2.0 && < 3
699 , QuickCheck >= 2.10 && < 2.15
700 , transformers >= 0.4 && < 0.6
701 default-language: Haskell2010
703test-suite data-array-test
705 type: exitcode-stdio-1.0
706 main-is: Streamly/Test/Array.hs
707 js-sources: jsbits/clock.js
712 , QuickCheck >= 2.10 && < 2.15
713 , hspec >= 2.0 && < 3
714 default-language: Haskell2010
716test-suite smallarray-test
718 type: exitcode-stdio-1.0
719 main-is: Streamly/Test/Array.hs
720 js-sources: jsbits/clock.js
722 cpp-options: -DTEST_SMALL_ARRAY
726 , QuickCheck >= 2.10 && < 2.15
727 , hspec >= 2.0 && < 3
728 default-language: Haskell2010
730test-suite primarray-test
732 type: exitcode-stdio-1.0
733 main-is: Streamly/Test/Array.hs
734 js-sources: jsbits/clock.js
736 cpp-options: -DDATA_ARRAY_PRIM
740 , QuickCheck >= 2.10 && < 2.15
741 , hspec >= 2.0 && < 3
742 default-language: Haskell2010
744test-suite prim-pinned-array-test
746 type: exitcode-stdio-1.0
747 main-is: Streamly/Test/Array.hs
748 js-sources: jsbits/clock.js
750 cpp-options: -DDATA_ARRAY_PRIM_PINNED
754 , QuickCheck >= 2.10 && < 2.15
755 , hspec >= 2.0 && < 3
756 default-language: Haskell2010
758test-suite string-test
760 type: exitcode-stdio-1.0
762 js-sources: jsbits/clock.js
767 , QuickCheck >= 2.10 && < 2.15
768 , hspec >= 2.0 && < 3
769 default-language: Haskell2010
773 type: exitcode-stdio-1.0
774 default-language: Haskell2010
776 js-sources: jsbits/clock.js
783 , hspec >= 2.0 && < 3
784 , random >= 1.0.0 && < 2
790 type: exitcode-stdio-1.0
791 default-language: Haskell2010
798test-suite nested-loops
800 type: exitcode-stdio-1.0
801 default-language: Haskell2010
802 main-is: nested-loops.hs
807 , random >= 1.0.0 && < 2
809test-suite parallel-loops
811 type: exitcode-stdio-1.0
812 default-language: Haskell2010
813 main-is: parallel-loops.hs
818 , random >= 1.0.0 && < 2
820test-suite version-bounds
822 type: exitcode-stdio-1.0
823 default-language: Haskell2010
824 main-is: version-bounds.hs
831-------------------------------------------------------------------------------
833-------------------------------------------------------------------------------
835executable SearchQuery
837 main-is: SearchQuery.hs
838 hs-source-dirs: examples
839 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
844 , http-conduit >= 2.2.2 && < 2.4
851 hs-source-dirs: examples
852 if flag(examples) || flag(examples-sdl)
862 main-is: MergeSort.hs
863 hs-source-dirs: examples
864 if flag(examples) || flag(examples-sdl)
869 , random >= 1.0.0 && < 2
876 hs-source-dirs: examples
877 if flag(examples) || flag(examples-sdl)
886executable CirclingSquare
888 main-is: CirclingSquare.hs
889 hs-source-dirs: examples
890 if flag(examples-sdl)
895 , SDL >= 0.6.5 && < 0.7
899executable ControlFlow
901 main-is: ControlFlow.hs
902 hs-source-dirs: examples
903 if flag(examples) || flag(examples-sdl)
908 , exceptions >= 0.8 && < 0.11
909 , transformers >= 0.4 && < 0.6
910 , transformers-base >= 0.4 && < 0.5
917 hs-source-dirs: examples
918 if flag(examples) || flag(examples-sdl)
926executable FileIOExamples
928 main-is: FileIOExamples.hs
929 hs-source-dirs: examples
930 if flag(examples) || flag(examples-sdl)
940 main-is: EchoServer.hs
941 hs-source-dirs: examples
942 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
947 , network >= 2.6 && < 4
951executable FileSinkServer
953 main-is: FileSinkServer.hs
954 hs-source-dirs: examples
955 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
960 , network >= 2.6 && < 4
964executable FromFileClient
966 main-is: FromFileClient.hs
967 hs-source-dirs: examples
968 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
976executable WordClassifier
978 main-is: WordClassifier.hs
979 hs-source-dirs: examples
980 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
985 , hashable >= 1.2 && < 1.4
986 , unordered-containers >= 0.2 && < 0.3
992 main-is: WordCount.hs
993 hs-source-dirs: examples
994 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
999 , vector >= 0.12 && < 0.13
1005 main-is: CamelCase.hs
1006 hs-source-dirs: examples
1007 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
1011 , base >= 4.9 && < 5
1018 hs-source-dirs: examples
1019 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
1023 , base >= 4.9 && < 5
1030 hs-source-dirs: examples
1031 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
1035 , base >= 4.9 && < 5
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list