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==7.10.3
90maintainer: streamly@composewell.com
91copyright: 2017 Harendra Kumar
92category: Control, Concurrency, Streaming, Reactivity
93stability: Experimental
99 credits/base-4.12.0.0.txt
100 credits/bjoern-2008-2009.txt
101 credits/clock-0.7.2.txt
102 credits/foldl-1.4.5.txt
103 credits/pipes-concurrency-2.0.8.txt
104 credits/pipes-concurrency.txt
105 credits/transient-0.5.5.txt
106 credits/vector-0.12.0.2.txt
107 credits/Yampa-0.10.6.2.txt
109 docs/streamly-vs-async.md
110 docs/streamly-vs-lists.md
117 src/Streamly/Internal/Data/Stream/Instances.hs
121 src/Streamly/Internal/Data/Time/config.h.in
127 src/Streamly/Internal/Data/Time/config.h
129source-repository head
131 location: https://github.com/composewell/streamly
134 description: Enable inspection testing
139 description: Debug build with asserts enabled
144 description: Development build
149 description: Use llvm backend for better performance
154 description: Disable chart generation
159 description: Disable rewrite rules
164 description: Use CPS style streams when possible
169 description: Build including examples
174 description: Build including SDL examples
178-------------------------------------------------------------------------------
180-------------------------------------------------------------------------------
182common compile-options
183 default-language: Haskell2010
185 cpp-options: -DUSE_STREAMK_ONLY
188 cpp-options: -DDISABLE_FUSION
191 cpp-options: -DDEVBUILD
194 cpp-options: -DINSPECTION
202 ghc-options: -Wmissed-specialisations
203 -Wall-missed-specialisations
205 if flag(dev) || flag(debug)
206 ghc-options: -fno-ignore-asserts
209 ghc-options: -Wcompat
210 -Wunrecognised-warning-flags
212 -Wincomplete-record-updates
213 -Wincomplete-uni-patterns
214 -Wredundant-constraints
215 -Wnoncanonical-monad-instances
217common optimization-options
219 -fspec-constr-recursive=16
222common threading-options
223 ghc-options: -threaded
226-- We need optimization options here to optimize internal (non-inlined)
227-- versions of functions. Also, we have some benchmarking inspection tests
228-- part of the library when built with --benchmarks flag. Thos tests fail
229-- if we do not use optimization options here. It was observed that due to
230-- -O2 here some concurrent/nested benchmarks improved and others regressed.
231-- We can investigate a bit more here why the regression occurred.
233 import: compile-options, optimization-options
235-- Compilation for coverage builds on CI machines takes too long without -O0
236-- XXX we should use coverage flag for that, -O0 may take too long to run tests
239 import: compile-options, threading-options
243-- Used by maxrate test, benchmarks and executables
245 import: compile-options, optimization-options, threading-options
247-- Some benchmarks are threaded some are not
248-- XXX dependencies should be separated under bench-depends
250 import: compile-options, optimization-options
251 ghc-options: -with-rtsopts "-T -M256M"
252 build-depends: mtl >= 2.2 && < 3
254common bench-options-threaded
255 import: compile-options, optimization-options
256 -- -threaded and -N2 is important because some GC and space leak issues
257 -- trigger only with these options.
258 ghc-options: -threaded -with-rtsopts "-T -N2 -M256M"
259 build-depends: mtl >= 2.2 && < 3
261-------------------------------------------------------------------------------
263-------------------------------------------------------------------------------
267 js-sources: jsbits/clock.js
268 include-dirs: src/Streamly/Internal/Data/Time
271 c-sources: src/Streamly/Internal/Data/Time/Windows.c
273 c-sources: src/Streamly/Internal/Data/Time/Darwin.c
277 , Streamly.Data.SmallArray
280 Streamly.Memory.Malloc
281 , Streamly.Memory.Ring
283 , Streamly.FileSystem.IOVec
284 , Streamly.FileSystem.FDIO
285 , Streamly.FileSystem.FD
291 , Streamly.Data.Unfold
292 , Streamly.Data.Unicode.Stream
295 , Streamly.Memory.Array
296 , Streamly.FileSystem.Handle
301 , Streamly.Internal.Control.Monad
302 , Streamly.Internal.Data.Strict
303 , Streamly.Internal.Data.Atomics
304 , Streamly.Internal.Data.Time
305 , Streamly.Internal.Data.Time.Units
306 , Streamly.Internal.Data.Time.Clock
307 , Streamly.Internal.Data.SVar
308 , Streamly.Internal.Data.Array
309 , Streamly.Internal.Data.SmallArray
310 , Streamly.Internal.Memory.Array.Types
311 , Streamly.Internal.Memory.Array
312 , Streamly.Internal.Memory.ArrayStream
313 , Streamly.Internal.Data.Fold.Types
314 , Streamly.Internal.Data.Fold
315 , Streamly.Internal.Data.Sink.Types
316 , Streamly.Internal.Data.Sink
319 , Streamly.Internal.Data.Stream.StreamK.Type
320 , Streamly.Internal.Data.Stream.StreamK
321 , Streamly.Internal.Data.Stream.StreamD.Type
322 , Streamly.Internal.Data.Stream.StreamD
323 , Streamly.Internal.Data.Stream.StreamDK.Type
324 , Streamly.Internal.Data.Stream.StreamDK
325 , Streamly.Internal.Data.Stream.Enumeration
326 , Streamly.Internal.Data.Stream.Prelude
328 -- Higher level streams
329 , Streamly.Internal.Data.Stream.SVar
330 , Streamly.Internal.Data.Stream.Serial
331 , Streamly.Internal.Data.Stream.Async
332 , Streamly.Internal.Data.Stream.Parallel
333 , Streamly.Internal.Data.Stream.Ahead
334 , Streamly.Internal.Data.Stream.Zip
335 , Streamly.Internal.Data.Stream.Combinators
336 , Streamly.Internal.Data.Unfold.Types
337 , Streamly.Internal.Data.Unfold
338 , Streamly.Internal.Data.Pipe.Types
339 , Streamly.Internal.Data.Pipe
340 , Streamly.Internal.Data.List
341 , Streamly.Internal.FileSystem.Handle
342 , Streamly.Internal.FileSystem.Dir
343 , Streamly.Internal.FileSystem.File
344 , Streamly.Internal.Data.Unicode.Stream
345 , Streamly.Internal.Data.Unicode.Char
346 , Streamly.Internal.Memory.Unicode.Array
347 , Streamly.Internal.Prelude
350 , Streamly.Internal.Mutable.Prim.Var
354 Streamly.Network.Socket
355 , Streamly.Network.Inet.TCP
357 , Streamly.Internal.Network.Socket
358 , Streamly.Internal.Network.Inet.TCP
361 -- Core libraries shipped with ghc, the min and max
362 -- constraints of these libraries should match with
363 -- the GHC versions we support
365 , containers >= 0.5 && < 0.7
366 , deepseq >= 1.4.1 && < 1.5
367 , directory >= 1.3 && < 1.4
368 , ghc-prim >= 0.2 && < 0.6
369 , transformers >= 0.4 && < 0.6
371 , heaps >= 0.3 && < 0.4
372 , primitive >= 0.6.4.0 && < 0.8
375 , atomic-primops >= 0.8 && < 0.9
376 , lockfree-queue >= 0.2.3 && < 0.3
379 , exceptions >= 0.8 && < 0.11
380 , monad-control >= 1.0 && < 2
382 , transformers-base >= 0.4 && < 0.5
386 network >= 2.6 && < 4
389 semigroups >= 0.18 && < 0.19
391 -- Array uses a Storable constraint in dev build making several inspection
393 if flag(dev) && flag(inspection)
394 build-depends: inspection-and-dev-flags-cannot-be-used-together
396-------------------------------------------------------------------------------
398-------------------------------------------------------------------------------
402 type: exitcode-stdio-1.0
404 js-sources: jsbits/clock.js
409 , hspec >= 2.0 && < 3
410 , containers >= 0.5 && < 0.7
411 , transformers >= 0.4 && < 0.6
413 , exceptions >= 0.8 && < 0.11
414 default-language: Haskell2010
416test-suite internal-prelude-test
418 type: exitcode-stdio-1.0
419 main-is: Streamly/Test/Internal/Prelude.hs
420 js-sources: jsbits/clock.js
425 , QuickCheck >= 2.10 && < 2.14
426 , hspec >= 2.0 && < 3
427 default-language: Haskell2010
429test-suite pure-streams-base
431 type: exitcode-stdio-1.0
432 main-is: PureStreams.hs
437 , hspec >= 2.0 && < 3
438 default-language: Haskell2010
440test-suite pure-streams-streamly
442 type: exitcode-stdio-1.0
443 main-is: PureStreams.hs
445 cpp-options: -DUSE_STREAMLY_LIST
449 , hspec >= 2.0 && < 3
450 default-language: Haskell2010
454 type: exitcode-stdio-1.0
456 js-sources: jsbits/clock.js
461 , QuickCheck >= 2.10 && < 2.14
462 , hspec >= 2.0 && < 3
465 transformers >= 0.4 && < 0.6
466 default-language: Haskell2010
470 type: exitcode-stdio-1.0
471 main-is: Streamly/Test/Array.hs
472 js-sources: jsbits/clock.js
474 cpp-options: -DTEST_ARRAY
478 , QuickCheck >= 2.10 && < 2.14
479 , hspec >= 2.0 && < 3
482 transformers >= 0.4 && < 0.6
483 default-language: Haskell2010
485test-suite internal-data-fold-test
487 type: exitcode-stdio-1.0
488 main-is: Streamly/Test/Internal/Data/Fold.hs
489 js-sources: jsbits/clock.js
494 , hspec >= 2.0 && < 3
495 , QuickCheck >= 2.10 && < 2.14
496 default-language: Haskell2010
498test-suite data-array-test
500 type: exitcode-stdio-1.0
501 main-is: Streamly/Test/Array.hs
502 js-sources: jsbits/clock.js
507 , QuickCheck >= 2.10 && < 2.14
508 , hspec >= 2.0 && < 3
511 transformers >= 0.4 && < 0.6
512 default-language: Haskell2010
514test-suite smallarray-test
516 type: exitcode-stdio-1.0
517 main-is: Streamly/Test/Array.hs
518 js-sources: jsbits/clock.js
520 cpp-options: -DTEST_SMALL_ARRAY
524 , QuickCheck >= 2.10 && < 2.14
525 , hspec >= 2.0 && < 3
528 transformers >= 0.4 && < 0.6
529 default-language: Haskell2010
531test-suite string-test
533 type: exitcode-stdio-1.0
535 js-sources: jsbits/clock.js
540 , QuickCheck >= 2.10 && < 2.14
541 , hspec >= 2.0 && < 3
544 transformers >= 0.4 && < 0.6
545 default-language: Haskell2010
549 type: exitcode-stdio-1.0
550 default-language: Haskell2010
552 js-sources: jsbits/clock.js
559 , clock >= 0.7.1 && < 0.9
560 , hspec >= 2.0 && < 3
561 , random >= 1.0.0 && < 2
567 type: exitcode-stdio-1.0
568 default-language: Haskell2010
575test-suite nested-loops
577 type: exitcode-stdio-1.0
578 default-language: Haskell2010
579 main-is: nested-loops.hs
584 , random >= 1.0.0 && < 2
586test-suite parallel-loops
588 type: exitcode-stdio-1.0
589 default-language: Haskell2010
590 main-is: parallel-loops.hs
595 , random >= 1.0.0 && < 2
597-------------------------------------------------------------------------------
599-------------------------------------------------------------------------------
601-- For linear, linear-async, linear-rate, nested and nested-concurrent
602-- you can pass the number of elements in the stream using the
603-- --stream-size option:
604-- $ cabal run linear -- --stream-size 1000000
607 import: bench-options
608 type: exitcode-stdio-1.0
609 hs-source-dirs: benchmark
611 other-modules: Streamly.Benchmark.Prelude, Common
615 , deepseq >= 1.4.1 && < 1.5
616 , random >= 1.0 && < 2.0
617 , gauge >= 0.2.4 && < 0.3
620 transformers >= 0.4 && < 0.6
622 build-depends: template-haskell >= 2.14 && < 2.16
623 , inspection-testing >= 0.4 && < 0.5
626 import: bench-options
627 type: exitcode-stdio-1.0
628 hs-source-dirs: benchmark
630 other-modules: NestedOps, Common
634 , deepseq >= 1.4.1 && < 1.5
635 , random >= 1.0 && < 2.0
636 , gauge >= 0.2.4 && < 0.3
639 transformers >= 0.4 && < 0.6
641benchmark nested-unfold
642 import: bench-options
643 type: exitcode-stdio-1.0
644 hs-source-dirs: benchmark
645 main-is: NestedUnfold.hs
646 other-modules: NestedUnfoldOps, Common
650 , deepseq >= 1.4.1 && < 1.5
651 , random >= 1.0 && < 2.0
652 , gauge >= 0.2.4 && < 0.3
655 transformers >= 0.4 && < 0.6
657benchmark unpinned-array
658 import: bench-options
659 type: exitcode-stdio-1.0
660 hs-source-dirs: benchmark
661 main-is: Streamly/Benchmark/Data/Array.hs
662 other-modules: Streamly.Benchmark.Data.ArrayOps
666 , deepseq >= 1.4.1 && < 1.5
667 , random >= 1.0 && < 2.0
668 , gauge >= 0.2.4 && < 0.3
671 transformers >= 0.4 && < 0.6
674 import: bench-options
675 type: exitcode-stdio-1.0
676 hs-source-dirs: benchmark
677 main-is: Streamly/Benchmark/Data/SmallArray.hs
678 other-modules: Streamly.Benchmark.Data.SmallArrayOps
682 , deepseq >= 1.4.1 && < 1.5
683 , random >= 1.0 && < 2.0
684 , gauge >= 0.2.4 && < 0.3
687 transformers >= 0.4 && < 0.6
690 import: bench-options
691 type: exitcode-stdio-1.0
692 hs-source-dirs: benchmark
694 other-modules: ArrayOps
698 , deepseq >= 1.4.1 && < 1.5
699 , random >= 1.0 && < 2.0
700 , gauge >= 0.2.4 && < 0.3
703 transformers >= 0.4 && < 0.6
706 import: bench-options
707 type: exitcode-stdio-1.0
708 -- A value of 400 works better for some benchmarks, however, it takes
709 -- extraordinary amount of time to compile with that.
710 -- ghc-options: -funfolding-use-threshold=150
711 hs-source-dirs: benchmark
713 other-modules: Streamly.Benchmark.FileIO.Array
714 , Streamly.Benchmark.FileIO.Stream
718 , gauge >= 0.2.4 && < 0.3
719 , typed-process >= 0.2.3 && < 0.3
720 , deepseq >= 1.4.1 && < 1.5
722 build-depends: template-haskell >= 2.14 && < 2.16
723 , inspection-testing >= 0.4 && < 0.5
725-------------------------------------------------------------------------------
726-- Threaded Benchmarks
727-------------------------------------------------------------------------------
729benchmark linear-async
730 import: bench-options-threaded
731 type: exitcode-stdio-1.0
732 hs-source-dirs: benchmark
733 main-is: LinearAsync.hs
734 other-modules: Streamly.Benchmark.Prelude, Common
738 , deepseq >= 1.4.1 && < 1.5
739 , random >= 1.0 && < 2.0
740 , gauge >= 0.2.4 && < 0.3
743 transformers >= 0.4 && < 0.6
745 build-depends: template-haskell >= 2.14 && < 2.16
746 , inspection-testing >= 0.4 && < 0.5
748benchmark nested-concurrent
749 import: bench-options-threaded
750 type: exitcode-stdio-1.0
751 hs-source-dirs: benchmark
752 main-is: NestedConcurrent.hs
753 other-modules: NestedOps, Common
757 , deepseq >= 1.4.1 && < 1.5
758 , random >= 1.0 && < 2.0
759 , gauge >= 0.2.4 && < 0.3
762 transformers >= 0.4 && < 0.6
765 import: bench-options-threaded
766 type: exitcode-stdio-1.0
767 hs-source-dirs: benchmark
769 other-modules: Streamly.Benchmark.Prelude, NestedOps, Common
773 , deepseq >= 1.4.1 && < 1.5
774 , random >= 1.0 && < 2.0
775 , gauge >= 0.2.4 && < 0.3
778 transformers >= 0.4 && < 0.6
780 build-depends: template-haskell >= 2.14 && < 2.16
781 , inspection-testing >= 0.4 && < 0.5
784 import: bench-options-threaded
785 type: exitcode-stdio-1.0
786 hs-source-dirs: benchmark
787 main-is: LinearRate.hs
788 other-modules: Streamly.Benchmark.Prelude, Common
792 , deepseq >= 1.4.1 && < 1.5
793 , random >= 1.0 && < 2.0
794 , gauge >= 0.2.4 && < 0.3
797 transformers >= 0.4 && < 0.6
799 build-depends: template-haskell >= 2.14 && < 2.16
800 , inspection-testing >= 0.4 && < 0.5
803 import: bench-options-threaded
804 type: exitcode-stdio-1.0
805 hs-source-dirs: benchmark
806 main-is: Concurrent.hs
812 , gauge >= 0.2.4 && < 0.3
816-------------------------------------------------------------------------------
817-- Internal benchmarks
818-------------------------------------------------------------------------------
821 import: bench-options
822 type: exitcode-stdio-1.0
823 hs-source-dirs: benchmark
824 main-is: BaseStreams.hs
825 other-modules: StreamDOps
834 , deepseq >= 1.4.1 && < 1.5
835 , random >= 1.0 && < 2.0
836 , gauge >= 0.2.4 && < 0.3
841 import: bench-options
842 hs-source-dirs: benchmark
843 main-is: NanoBenchmarks.hs
849 , gauge >= 0.2.4 && < 0.3
850 , random >= 1.0 && < 2.0
855 import: bench-options
856 type: exitcode-stdio-1.0
857 hs-source-dirs: benchmark
859 default-language: Haskell2010
865 , gauge >= 0.2.4 && < 0.3
866 , random >= 1.0 && < 2.0
871 default-language: Haskell2010
873 hs-source-dirs: benchmark
875 if flag(dev) && !flag(no-charts) && !impl(ghcjs)
879 , bench-show >= 0.3 && < 0.4
881 , transformers >= 0.4 && < 0.6
885-------------------------------------------------------------------------------
887-------------------------------------------------------------------------------
889executable SearchQuery
891 main-is: SearchQuery.hs
892 hs-source-dirs: examples
893 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
898 , http-conduit >= 2.2.2 && < 2.4
905 hs-source-dirs: examples
906 if flag(examples) || flag(examples-sdl)
911 , directory >= 1.3 && < 1.4
914 transformers >= 0.4 && < 0.6
920 main-is: MergeSort.hs
921 hs-source-dirs: examples
922 if flag(examples) || flag(examples-sdl)
927 , random >= 1.0.0 && < 2
934 hs-source-dirs: examples
935 if flag(examples) || flag(examples-sdl)
943 semigroups >= 0.18 && < 0.19
944 , transformers >= 0.4 && < 0.6
948executable CirclingSquare
950 main-is: CirclingSquare.hs
951 hs-source-dirs: examples
952 if flag(examples-sdl)
957 , SDL >= 0.6.5 && < 0.7
961executable ControlFlow
963 main-is: ControlFlow.hs
964 hs-source-dirs: examples
965 if flag(examples) || flag(examples-sdl)
970 , exceptions >= 0.8 && < 0.11
971 , transformers >= 0.4 && < 0.6
972 , transformers-base >= 0.4 && < 0.5
975 semigroups >= 0.18 && < 0.19
982 hs-source-dirs: examples
983 if flag(examples) || flag(examples-sdl)
991executable FileIOExamples
993 main-is: FileIOExamples.hs
994 hs-source-dirs: examples
995 if flag(examples) || flag(examples-sdl)
1003executable EchoServer
1005 main-is: EchoServer.hs
1006 hs-source-dirs: examples
1007 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
1011 , base >= 4.8 && < 5
1012 , network >= 2.6 && < 4
1015 transformers >= 0.4 && < 0.6
1019executable FileSinkServer
1021 main-is: FileSinkServer.hs
1022 hs-source-dirs: examples
1023 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
1027 , base >= 4.8 && < 5
1028 , network >= 2.6 && < 4
1031 transformers >= 0.4 && < 0.6
1035executable FromFileClient
1037 main-is: FromFileClient.hs
1038 hs-source-dirs: examples
1039 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
1043 , base >= 4.8 && < 5
1047executable WordClassifier
1049 main-is: WordClassifier.hs
1050 hs-source-dirs: examples
1051 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
1055 , base >= 4.8 && < 5
1056 , hashable >= 1.2 && < 1.4
1057 , unordered-containers >= 0.2 && < 0.3
1063 main-is: WordCount.hs
1064 hs-source-dirs: examples
1065 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
1069 , base >= 4.8 && < 5
1070 , vector >= 0.12 && < 0.13
1076 main-is: CamelCase.hs
1077 hs-source-dirs: examples
1078 if (flag(examples) || flag(examples-sdl)) && !impl(ghcjs)
1082 , base >= 4.8 && < 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