2020-06-30 00:32:37 +03:00
|
|
|
<!--
|
|
|
|
Portions (c) 2020, Google LLC.
|
|
|
|
SPDX-License-Identifer: BSD-3-Clause
|
|
|
|
-->
|
2019-06-26 15:37:55 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
# Getting started with the `streamly` package
|
2020-05-13 17:44:15 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
This guide will show you how to write a simple program that uses
|
2021-06-02 14:15:09 +03:00
|
|
|
[Streamly][], using the [`cabal`](https://www.haskell.org/cabal/) build
|
2020-06-30 00:32:37 +03:00
|
|
|
manager for Haskell.
|
2020-05-13 17:44:15 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
<!-- TODO: Add instructions for `stack` and `nix`.
|
2020-05-13 17:44:15 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
If you are using `stack` or `nix` please make sure to add the latest
|
|
|
|
version from Hackage to your tool configuration. -->
|
2019-06-26 15:37:55 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
No prior knowledge of either Haskell or of `cabal` is needed. We do
|
|
|
|
however assume that you are using a command-line shell on a POSIX
|
|
|
|
operating system. If you are running Windows™ then you may need
|
|
|
|
to run a command-line shell under `msys` and some of the commands
|
|
|
|
below may also need to be changed in small ways to make them work.
|
2019-06-26 15:37:55 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
**Note**: If you are new to Haskell you may find the [Haskell Getting
|
2021-06-02 14:15:09 +03:00
|
|
|
Started Guide][haskell-getting-started] to be useful.
|
2020-05-13 17:44:15 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
If you know your way around Haskell, and have an up to date toolchain
|
|
|
|
already installed, then you can jump straight to the section titled
|
2021-06-02 14:15:09 +03:00
|
|
|
"[_Prepare Your Build Directory_](#prepare-your-build-directory)".
|
2020-05-13 17:44:15 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
## Getting started with `streamly` using `cabal`
|
2019-06-26 15:37:55 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
To get started, you will need a recent `cabal` binary to be installed
|
|
|
|
on your system.
|
|
|
|
|
|
|
|
### Installing `cabal`
|
|
|
|
|
|
|
|
A pre-packaged `cabal` binary may already be available for your
|
|
|
|
operating system.
|
|
|
|
|
|
|
|
For example, on Debian GNU/Linux, you could install `cabal` using::
|
|
|
|
|
|
|
|
```
|
|
|
|
$ sudo apt install cabal-install
|
|
|
|
```
|
|
|
|
|
|
|
|
### Installing `ghc`
|
|
|
|
|
|
|
|
You would also need to install the Glasgow Haskell Compiler `ghc`. In
|
|
|
|
most operating systems, using the system's package manager to install
|
|
|
|
`cabal` would also bring in a version of `ghc` as a dependency.
|
|
|
|
|
|
|
|
Please verify that `ghc` is present:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ ghc --version
|
|
|
|
The Glorious Glasgow Haskell Compilation System, version 8.0.2
|
|
|
|
```
|
|
|
|
|
|
|
|
If `ghc` isn't present, please install it using your operating
|
|
|
|
system's package manager. For example, on Debian GNU/Linux, use:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ sudo apt install ghc
|
|
|
|
```
|
|
|
|
|
|
|
|
### Update `cabal` if necessary
|
|
|
|
|
|
|
|
Many operating systems ship an old version of `cabal`; in order to use
|
|
|
|
`streamly` you should use `cabal` version 3.0 (or later).
|
|
|
|
|
|
|
|
You can check the installed version of `cabal` by using its
|
|
|
|
`--version` flag:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ which cabal
|
|
|
|
/usr/bin/cabal
|
|
|
|
$ /usr/bin/cabal --version
|
|
|
|
cabal-install version 1.24.0.2
|
|
|
|
compiled using version 1.24.2.0 of the Cabal library
|
|
|
|
```
|
|
|
|
|
|
|
|
In this example, the installed `cabal` binary is too old for our
|
|
|
|
needs. It would need to be upgraded.
|
|
|
|
|
|
|
|
You can ask `cabal` to upgrade itself (please see
|
|
|
|
<https://www.haskell.org/cabal/>):
|
|
|
|
|
|
|
|
```
|
|
|
|
$ cabal install Cabal cabal-install
|
|
|
|
Resolving dependencies...
|
|
|
|
Downloading base16-bytestring-0.1.1.7...
|
|
|
|
... lots of build output ...
|
|
|
|
Building cabal-install-3.0.0.0...
|
|
|
|
Installed cabal-install-3.0.0.0
|
|
|
|
```
|
|
|
|
|
|
|
|
`cabal` will usually place its compiled binaries inside the directory
|
|
|
|
`$HOME/.cabal/bin`.
|
|
|
|
|
|
|
|
You can verify the version of your newly installed binary by using the
|
|
|
|
`--version` flag again:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ $HOME/.cabal/bin/cabal --version
|
|
|
|
cabal-install version 3.0.0.0
|
|
|
|
compiled using version 3.0.2.0 of the Cabal library
|
|
|
|
```
|
|
|
|
|
|
|
|
If you have upgraded `cabal`, do be sure to specify `$HOME/.cabal/bin`
|
|
|
|
early in your `PATH` shell variable, so that the new binary gets used
|
|
|
|
instead of the older version on your system.
|
|
|
|
|
|
|
|
```
|
|
|
|
$ PATH=$HOME/.cabal/bin:$PATH
|
|
|
|
```
|
|
|
|
|
|
|
|
Once you have `cabal` version 3.0 (or later) successfully installed,
|
|
|
|
please refresh its package list by using `cabal update`.
|
2019-06-26 15:37:55 +03:00
|
|
|
|
|
|
|
```
|
2020-04-16 02:19:03 +03:00
|
|
|
$ cabal update
|
2020-06-30 00:32:37 +03:00
|
|
|
Downloading the latest package list from hackage.haskell.org
|
2019-06-26 15:37:55 +03:00
|
|
|
```
|
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
### Prepare Your Build Directory
|
|
|
|
|
|
|
|
Next, create a build directory, so that you can use `cabal`'s isolated
|
|
|
|
builds feature.
|
2020-05-13 17:44:15 +03:00
|
|
|
|
|
|
|
```
|
|
|
|
$ mkdir streamly-play
|
2020-06-30 00:32:37 +03:00
|
|
|
$ cd streamly-play
|
2020-05-13 17:44:15 +03:00
|
|
|
```
|
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
Run `cabal init` to create an initial set of project files:
|
2020-05-13 17:44:15 +03:00
|
|
|
|
|
|
|
```
|
|
|
|
$ cabal init --minimal --dependency base --dependency streamly
|
2020-06-30 00:32:37 +03:00
|
|
|
|
|
|
|
Generating LICENSE...
|
|
|
|
... other messages ...
|
|
|
|
Generating Main.hs...
|
|
|
|
Generating streamly-play.cabal...
|
|
|
|
|
|
|
|
Warning: no synopsis given. You should edit the .cabal file and add one.
|
|
|
|
You may want to edit the .cabal file and add a Description field.
|
2020-05-13 17:44:15 +03:00
|
|
|
```
|
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
This invocation will set up a build with two build dependencies,
|
|
|
|
namely `base` and `streamly`. You can add additional dependencies
|
|
|
|
later, by editing the `build-depends` section of the generated cabal
|
|
|
|
file `streamly-play.cabal`. Please see the [Cabal User
|
|
|
|
Guide](https://www.haskell.org/cabal/users-guide/) for more
|
|
|
|
information on how to configure `cabal`.
|
2020-05-13 17:44:15 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
This invocation also creates a skeletal `Main.hs` program which we
|
|
|
|
will use later.
|
2019-06-26 15:37:55 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
### Try `streamly` in the GHCi REPL
|
|
|
|
|
|
|
|
You can now try out `streamly` using the `GHCi` interpreter's
|
|
|
|
read-eval-print-loop (REPL) facility.
|
|
|
|
|
|
|
|
To start up the GHCi REPL using the released `streamly` version on
|
|
|
|
Hackage, please use:
|
2020-05-13 17:44:15 +03:00
|
|
|
|
2019-06-26 15:37:55 +03:00
|
|
|
```
|
2020-04-16 02:19:03 +03:00
|
|
|
$ cabal repl --build-depends streamly
|
2020-06-30 00:32:37 +03:00
|
|
|
... plenty of build messaages, the first time around ...
|
2020-05-13 17:44:15 +03:00
|
|
|
GHCi, version 8.8.3: https://www.haskell.org/ghc/ :? for help
|
|
|
|
[1 of 1] Compiling Main ( Main.hs, interpreted )
|
|
|
|
Ok, one module loaded.
|
2020-06-30 00:32:37 +03:00
|
|
|
*Main>
|
|
|
|
```
|
|
|
|
|
|
|
|
Once at the `*Main>` prompt, you can import `streamly` and use it
|
|
|
|
directly:
|
|
|
|
|
|
|
|
```
|
2021-05-21 12:30:09 +03:00
|
|
|
*Main> import qualified Streamly.Prelude as Stream
|
2020-06-30 00:32:37 +03:00
|
|
|
|
2021-05-21 12:30:09 +03:00
|
|
|
*Main Stream> Stream.drain $ Stream.mapM print $ Stream.fromList [1..3]
|
2020-05-13 17:44:15 +03:00
|
|
|
1
|
|
|
|
2
|
|
|
|
3
|
2021-05-21 12:30:09 +03:00
|
|
|
*Main Stream>
|
2020-05-13 17:44:15 +03:00
|
|
|
```
|
2019-06-26 15:37:55 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
For the curious, here is a high level overview of what these lines
|
|
|
|
do:
|
|
|
|
|
2021-05-21 12:30:09 +03:00
|
|
|
1. `import qualified Streamly.Prelude as Stream` imports the Streamly
|
|
|
|
prelude into GHCi, and makes it available as module `Stream`.
|
2020-06-30 00:32:37 +03:00
|
|
|
2. `[1..3]` generates the Haskell list `[1, 2, 3]`.
|
2021-05-21 12:30:09 +03:00
|
|
|
3. `Stream.fromList` transforms that list into a stream of integers.
|
|
|
|
4. `Stream.mapM print` transforms the stream of integers into a stream of
|
2020-06-30 00:32:37 +03:00
|
|
|
actions that would print those integers when executed.
|
2021-05-21 12:30:09 +03:00
|
|
|
5. `Stream.drain` transforms that stream of actions into an IO action that
|
2020-06-30 00:32:37 +03:00
|
|
|
`main` or GHCi's REPL can execute.
|
|
|
|
|
|
|
|
These concepts are explained in greater detail in the [Streamly
|
|
|
|
Tutorial][tutorial].
|
|
|
|
|
|
|
|
#### Using a specific version of `streamly` in the REPL
|
|
|
|
|
|
|
|
You can also ask `cabal` to use a specific version of `streamly` by
|
|
|
|
adding a version number constraint to the `--build-depends` flag:
|
2020-05-13 17:44:15 +03:00
|
|
|
|
|
|
|
```
|
|
|
|
$ cabal repl --build-depends streamly==0.7.2
|
2020-06-30 00:32:37 +03:00
|
|
|
[1 of 1] Compiling Main ( Main.hs, interpreted )
|
|
|
|
Ok, modules loaded: Main.
|
|
|
|
*Main>
|
2019-06-26 15:37:55 +03:00
|
|
|
```
|
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
#### (Advanced) Using the development version of `streamly` in the REPL
|
|
|
|
|
|
|
|
To use the development version of `streamly`, we need to configure
|
|
|
|
`cabal` to fetch it from Github.
|
2019-06-26 15:37:55 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
Create a `cabal.project` file in the current directory with the
|
|
|
|
following content:
|
2019-06-26 15:37:55 +03:00
|
|
|
|
|
|
|
```
|
|
|
|
packages: .
|
|
|
|
source-repository-package
|
|
|
|
type: git
|
|
|
|
location: https://github.com/composewell/streamly
|
|
|
|
tag: master
|
|
|
|
```
|
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
With this file present, `cabal` will fetch and build the current
|
|
|
|
version of `streamly` from Github every time it is run. For example:
|
2019-06-26 15:37:55 +03:00
|
|
|
|
|
|
|
```
|
2020-04-16 02:19:03 +03:00
|
|
|
$ cabal repl
|
2020-06-30 00:32:37 +03:00
|
|
|
... fetches the 'master' branch of streamly from Github ...
|
|
|
|
... build messages ...
|
|
|
|
[1 of 1] Compiling Main v ( Main.hs, interpreted )
|
|
|
|
Ok, modules loaded: Main.
|
|
|
|
*Main>
|
2019-06-26 15:37:55 +03:00
|
|
|
```
|
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
### Using `streamly` in a standalone program
|
2020-04-16 02:19:03 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
Let us now turn the single-line stanza above into a standalone program
|
|
|
|
that uses `streamly`.
|
2020-04-16 02:19:03 +03:00
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
Edit `Main.hs` to contain the following:
|
|
|
|
|
|
|
|
```haskell
|
2020-05-13 17:44:15 +03:00
|
|
|
module Main where
|
2019-06-26 15:37:55 +03:00
|
|
|
|
2021-05-21 12:30:09 +03:00
|
|
|
import qualified Streamly.Prelude as Stream
|
2019-06-26 15:37:55 +03:00
|
|
|
|
2020-05-13 17:44:15 +03:00
|
|
|
main :: IO ()
|
2021-05-21 12:30:09 +03:00
|
|
|
main = Stream.drain $ Stream.mapM print $ Stream.fromList [1..3]
|
2019-06-26 15:37:55 +03:00
|
|
|
```
|
|
|
|
|
2020-06-30 00:32:37 +03:00
|
|
|
Build and run this program using `cabal run`:
|
2020-05-13 17:44:15 +03:00
|
|
|
|
2019-06-26 15:37:55 +03:00
|
|
|
```
|
2020-05-13 17:44:15 +03:00
|
|
|
$ cabal run
|
2020-06-30 00:32:37 +03:00
|
|
|
... build messages ...
|
|
|
|
1
|
|
|
|
2
|
|
|
|
3
|
2019-06-26 15:37:55 +03:00
|
|
|
```
|
2020-06-30 00:32:37 +03:00
|
|
|
|
|
|
|
## Which version of `streamly` should you use?
|
|
|
|
|
|
|
|
If you are new to Streamly, we recommend using latest [stable release
|
|
|
|
of streamly][streamly-hackage] on Hackage.
|
|
|
|
|
|
|
|
If you need access to cutting edge features (and do not mind the
|
|
|
|
occasional breakage), please use the [development version of
|
|
|
|
streamly][streamly-github] on Github.
|
|
|
|
|
|
|
|
|
|
|
|
## Next Steps
|
|
|
|
|
|
|
|
If you got this far successfully, congratulations!
|
|
|
|
|
|
|
|
* For an overview of the `streamly` package, please read the
|
2021-06-02 14:15:09 +03:00
|
|
|
[Streamly Quick Overview](README.md) and [Streamly Tutorial][tutorial].
|
2020-06-30 00:32:37 +03:00
|
|
|
* Please browse the code examples in the
|
2021-06-02 14:15:09 +03:00
|
|
|
[`Streamly examples repository`][streamly-examples].
|
2020-06-30 00:32:37 +03:00
|
|
|
* If you would like to start on a real world project, please take a
|
2021-06-02 14:15:09 +03:00
|
|
|
look at the [Streamly Build and Optimization Guide](./docs/Build.md).
|
|
|
|
* For more information please visit the [Streamly Homepage][Streamly].
|
2020-06-30 00:32:37 +03:00
|
|
|
|
|
|
|
<!-- Markdown Links -->
|
|
|
|
|
2021-06-02 14:15:09 +03:00
|
|
|
[Streamly]: https://streamly.composewell.com/
|
|
|
|
[tutorial]: https://hackage.haskell.org/package/streamly-0.7.3/docs/Streamly-Tutorial.html
|
2020-06-30 00:32:37 +03:00
|
|
|
[streamly-hackage]: https://hackage.haskell.org/package/streamly
|
|
|
|
[streamly-github]: https://github.com/composewell/streamly
|
2021-06-02 14:15:09 +03:00
|
|
|
[streamly-examples]: https://github.com/composewell/streamly-examples
|
|
|
|
[haskell-getting-started]: https://github.com/composewell/haskell-dev/blob/master/getting-started.rst
|