Haskell lab: functional programming with functions and types, in the browser
This lab gives each student a Haskell compiler of their own, with four small files to read, run and change: functions and types, lists, folds and recursion, and a type of their own. A Haskell program is made of functions that take values and give values back, and every function has a type that the compiler checks before anything runs.
It is not an attack lab. Every copy has no route to the internet and none to any other student, so nothing can be downloaded into it and nothing in it can reach anybody else. It has the compiler and the libraries that ship with it only: no extra packages can be installed, so there is no cabal install and no stack.
What students learn
That a program can be built from functions, and that a type says what each one takes and gives back. Students read a type signature, run a file, work out one expression, apply map and filter to a list, write a function that calls itself and see a fold do the same job, and meet a type error that stops a program before it runs. A fourth file adds a type of their own with two shapes and a function that takes it apart by matching on which shape it is. It suits an introduction to programming paradigms; check your own awarding body’s unit for the exact wording, none is quoted here.
Run it in your browser
The lab starts one service, haskell, from the official haskell image, running as an unprivileged account. There is no web page, so the lab bar has no link under In your browser, and the terminal is how you run code. It reaches the compiler with docker exec haskell, followed by runghc and a file name to run a file, or ghc -e and an expression in quotes to work out one expression. The compiler takes a couple of seconds to start each time. Every answer is the same each time, and everything printed is in English, whatever language the page is in.
For a conversation with the compiler, press Open terminal and type docker exec -it haskell ghci Lists.hs. At the ghci> prompt type an expression and press Enter, such as map (* 2) [1, 2, 3], which prints [2,4,6]. Type :t followed by a name to see its type, and :quit to leave.
- Open the Container page. Open Build on the bar and choose Run a container. Anybody may open it, and the Git lab and the SQL lab start with no account. Every other lab needs a free account: create one, sign in, then press Start.
- Find the lab. The Sample labs card lists every sample. Find Haskell: functions, types and lists.
- Press Start. Start runs it as it is, in one press. Edit the file first opens the compose file so you can change it before you start.
- Open it. There is no web page to open. On the lab’s page press Open terminal and type docker exec haskell runghc Basics.hs to run the first file: it prints Hello, Haskell!, then 49, then (True,False).
What to ask students to hand in
The expressions they tried and what each printed: one that calls a function from a file, one that uses map or filter on a list, and one that makes the compiler report a type error. Then a function of their own added to Basics.hs with its type signature and a call that shows it working, and a sentence or two in their own words on what a type signature tells the reader. Nothing is marked automatically: the function and the sentence show whether it was understood. For stronger work ask them to write the signature first and say what it promises.
A basic lesson on this lab
Haskell Basics is a small lesson worked in this lab. In it a student reads a function and its type, runs a file, applies a function to a list, folds a list and meets a type error.
Free personal accounts have it in the Basics module, which is on Home, and every college can copy it from the Library’s Basics folder. It is deliberately small: it shows a teacher what a lesson worked in a lab is, and the lab does the rest. Copy it into a module of your own to change it.
The code on GitHub
The compose file has no Dockerfile: it runs one official public image, Haskell with GHC, pinned to version 9.10.1, as an unprivileged account with 384 MB of memory. GHC is the hungry one: running a file, a single expression, the interactive prompt and a full compile of a file like these peaked near 250 MB counting the cache of the compiler’s own files, and the same work finished inside 192 MB, so 384 MB leaves room. The image and the compiler carry permissive open source licences and are not distributed by us. The file writes four small teaching files when it first starts and keeps them on a volume, so what a student changes is still there after a stop and a start. The limits are honest ones: there is no way out, so no extra packages, and a very large program may need more memory than the lab has.
Set it as work
Say in the task what to hand in.
- Make the lab. In your module add a task and choose the Container lab card, then In a GitHub repository. Give https://github.com/mitsurutech/lab-haskell-lab with the branch main. The compose file is the default, compose.yaml. Fork the repository first if you want to change it, for example to add more functions to the starting files.
- Publish and try it. Publish pins the commit you were shown, so a later change in the repository does not alter a lab you have already set. Start your own copy first.
- Hand it out. Assign it like any task, with a due date if you want one, and say in the task what to do and what to hand in.
- Mark what is handed in. Open a student’s copy and the work they handed in, mark it, and send it back with a reason if it needs more.
Try this lab, and what it costs
A free personal account can work through the basic lessons in this lab, with enough free credit each month to follow most lessons and no card. For a class, a school or college has its first 365 days free for up to 50 students, then pays per student a year, with every lab included and staff free.
Questions people ask
- Why is the first command slow?
- The compiler has to start and read its libraries each time, which takes a couple of seconds. Running a file with runghc or one expression with ghc -e does that every time. For many tries in a row use the interactive prompt, ghci, which starts once.
- Why do the names and messages stay in English on a page in another language?
- The greeting in the files, the words Just and Nothing and every message the compiler prints are English, and the lab does not change them. The lesson says so and explains each answer in the page’s own language.
- Can students install a package?
- No. The lab has no way out to the internet, so nothing can be downloaded: only the libraries that come with the compiler are there. Anything from those libraries, such as Data.Char, can be imported.