base
, but couple of other useful libraries.In case you don't already know, there has been a surge of online programming environments in recent years, most notably interactive notebooks and REPLs. This stuff is really popular the webdev and data science communities2.
The idea is that you can type in some commands, have them executed by whatever interpreter, write code in files/modules, build interactive programs, create visualizations, entire websites, and so on.
Here are the major examples I can think of for various languages:
That last one is what this post is about. Repl.it is great for many reasons, not least because it started providing a Haskell environment two years ago.
sidenote: repl.it lets multiple people join the same editor and all edit at the same time, which is insanely cool. Get some friends and click the "multiplayer" button.
Unfortunately it's not clear which packages apart from base
are built in. Random guessing quickly shows that at least containers
and text
are available, but I couldn't find a complete list anywhere. Of course we won't let that stop us. After a bit of fiddling and exploring:
:! ls -l /opt/ghc/8.6.3/lib/ghc-8.6.3/
:! ghc-pkg list
5
Explanation: :!
is a ghci command6 that lets you execute whatever you want in the shell.
We can see that we have access to the following7 libraries:
/opt/ghc/8.6.3/lib/ghc-8.6.3/package.conf.d
Cabal-2.4.0.1
array-0.5.3.0
base-4.12.0.0
binary-0.8.6.0
bytestring-0.10.8.2
containers-0.6.0.1
deepseq-1.4.4.0
directory-1.3.3.0
filepath-1.4.2.1
(ghc-8.6.3)
ghc-boot-8.6.3
ghc-boot-th-8.6.3
ghc-compact-0.1.0.0
ghc-heap-8.6.3
ghc-prim-0.5.3
ghci-8.6.3
haskeline-0.7.4.3
hpc-0.6.0.3
integer-gmp-1.0.2.0
libiserv-8.6.3
mtl-2.2.2
parsec-3.1.13.0
pretty-1.1.3.6
process-1.6.3.0
rts-1.0
stm-2.5.0.0
template-haskell-2.14.0.0
terminfo-0.4.1.2
text-1.2.3.1
time-1.8.0.2
transformers-0.5.5.0
unix-2.7.2.2
xhtml-3000.2.2.1
FUN. I don't know about you, but at this point I get pretty excited, since this means that we can write a lot more serious stuff than I had initially realized.
For example, we can write entire interactive command-line programs that repl.it will automatically serve up at https://[replname].[username].repl.run
. Here you can play with an example I simply copy-pasted from the haskeline documentation.
If you're not familiar with the libraries above, here's an (incomplete) overview:
Set
, Map
, Graph
, and Tree
. The first two are especially nice if you're used to dictionaries and sets from other languages.String
as the proper way to do either user-readable strings or binary data respectively.That's it for now, figure out the other libraries yourself. It would obviously be great to have more. For example to have wreq to make network requests, or some graphics package to create images or draw on the DOM.
With enough interest repl.it might be persuaded to include more packages. Before discovering all this, I messaged them on their twitter to ask if they could update GHC from 8.0.x to 8.6.3 in the coming year, and they literally did it within an afternoon. Amazing.
Now that you have no more excuses, I guess you just have to go and build stuff. If you're a newbie, then work through the exercises from Haskell Programming from first principles (paid, but very worth it), or Learn You a Haskell (free and utterly charming).
Use haskeline and go write a clone of Zork. Do whatever! Share what you make on r/haskell, and come ask questions in the #haskell channel on the functional programming discord.
Here is a code snippet so that you don't get bored in the meantime. Save it into a new file in repl.it, hit run and load up the module with something like :l Entropy.hs
.
Do you have the right intuition for what has high or low entropy? I didn't.
{-# LANGUAGE ScopedTypeVariables #-}
module Entropy where
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M
-- tally the number of occurrences of all the items in a list:
count :: forall a . Ord a => [a] -> Map a Int
count elements =
foldl addCount M.empty elements
where
addCount :: Map a Int -> a -> Map a Int
addCount counter el = M.insertWith (+) el 1 counter
-- calculate which element occurs which percentage of the time
proportions :: Ord a => [a] -> [Double]
proportions xs =
[c / n | c' <- counts, let c = fromIntegral c']
where
counts = M.elems (count xs)
n = fromIntegral $ length xs
-- entropy measure
-- https://en.wikipedia.org/wiki/Entropy#Statistical_mechanics
entropy :: Ord a => [a] -> Double
entropy xs =
-sum [p * logBase 2 p | p <- proportions xs]
Your main
function will be run in a little pseudo-terminal, so all your putStrLn
and getLine
will print text or wait for user input. You can't pass arguments or flags to your program tough, since you don't control stdin.
I was skeptical of online programming environments at first, since the idea sounds a bit gimmicky. I changed my mind8 after seeing how many children build really impressive things in them, and how joyful it feels to use one for quick demos and experiments. It's really easy to send somebody a code snippet that just executes, zero friction. Beginners can still install stack or cabal afterwards, no rush.
We also have our very own Haskell Kernel currently maintained by total champion Vaibhav Sagar. It's all there, but more help is needed to remove some frictions for beginners, like a noob-friendly install experience and more cool tutorials. EDIT: I'm being informed on reddit that you can actually use IHaskell online.
Get it? JuPytR!
I didn't know about ghc-pkg list
, but my friend Nicolas did.
I came across this in a list of all ghci commands, hoping for one that lists all importable modules for a specific ghci session.
Why precisely those? Turns out they are probably just the core packages that GHC ships with. Again, thanks Nicolas!
meta-footnote: Come to think of it, it was actually https://tryhaskell.org/ that got me all fired up about Haskell for the very first time.