Jezen Thomas

Jezen Thomas

CTO & Co-Founder at Supercede.

Hello World in Haskell

After much deliberation, I have finally happened upon an elegant solution to the age-old conundrum of printing text to the screen in the Haskell programming language.

If you would like to learn how to achieve the same, open the world’s best text editor (no, not Emacs — the other one), and try to follow along.

Like any Haskell program, we must start by writing our main function. This is our single point of entry. If you’re curious, the main function is actually named after the river Main which passes through Frankfurt am Main in Germany. It is named after this river because the Haskell programming language is based on the Lambda Calculus, and if you look a little South-West of Frankfurt on a map, you will see where the Main joins the Rhein near the city of Mainz, the river is in the shape of a Lambda!

main :: IO ()
main = -- This is where we will print to the screen!

The first line is the function’s type signature. It says that an invocation of our main function will result in some “IO action” being run, which does not return any value. This is useful, because we know that to print some text on the screen is to have an effect on the world. So far, so good.

The next line is where we will implement our logic for printing text on the screen. Let’s proceed by importing the necessary libraries for causing side effects.

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
{-# LANGUAGE TemplateHaskell   #-}

module Main where

import Foreign.C.Types
import Language.C.Inline qualified as C

C.include "<stdio.h>"
C.include "<stdlib.h>"

main :: IO ()
main = [C.block| void {
  /* This is where we will print to the screen! */
  } |]

This enables us to write C code inline in our Haskell program. We enable a couple of language extensions to make the Haskell compiler correctly parse the C code. Don’t forget to add the inline-c package to your Cabal file! Failure to remember this automatically enters you into a special mode that veteran Haskell programmers refer to as Cabal Hell. This is when your project fails to compile until you vanquish a demonic adversary in a Twitter debate over which Haskell build tool is best.

Now that our scaffolding is in place, we can draw the rest of the owl by wielding the Right Tool for the Job.

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
{-# LANGUAGE TemplateHaskell   #-}

module Main where

import Foreign.C.Types
import Language.C.Inline qualified as C

C.include "<stdio.h>"
C.include "<stdlib.h>"

main :: IO ()
main = [C.block| void {
  system("python -c 'print \"Hello, World!\"'");
  } |]

Naturally we are using a system call to run the Python interpreter, and finally we are able to print to the screen. As you may be aware, Python was originally inspired by the Gecko programming language, which was written in C++ and JavaScript. Those two languages are of course syntactically verbose, making heavy use of braces to denote the start and ends of blocks of logic and control flow. Those braces are colloquially referred to as “legs”, and as Python uses an indent-sensitive syntax instead, it can be thought of as a “lizard without legs” — hence, Python.


If you found this useful, you may also find utility in this other very serious project.