Learn you a Haskell
I’ve been reading about functional programming lately, and I want to learn a new language to try it out properly. I picked Haskell for a few reasons. First, it’s touted as a pure functional language, and that appeals to me because I want to learn functional programming in particular, and not have the concepts blurred by a hybrid language. Second, there’s a lot of good online resources that I can learn from. Third, it has a cool name.
There’s a couple of online tutorials I’ve found that seem to be well regarded. I’m working through them in parallel. Learn You A Haskell is a little more wordy (and funny!), Real World Haskell has more practical examples. Between the two of them I’m beginning to understand things. I also bought a new book called Exercises for Programmers: 57 Challenges to Develop Your Coding Skills to help me with some ideas for small programs to write and test my knowlege.
So without further ado, here is the first question in the book, and my first program in Haskell.
Create a simple tip calculator. The program should prompt for a bill amount and a tip rate. The program must compute the tip and display both the tip and the total amount of the bill.
import System.IO
main = do
hSetBuffering stdout NoBuffering
hSetBuffering stdin NoBuffering
putStr "What is the bill amount? "
billAmountInput <- getLine
putStr "What is the tip rate? "
tipRateInput <- getLine
let billAmount = read billAmountInput :: Float
let tipRate = read tipRateInput :: Float
let tip = billAmount * tipRate
let total = billAmount + tip;
putStrLn ("The tip is $" ++ show tip)
putStrLn ("The total is $" ++ show total)
To run this program in the ghci
interpreter:
- save the code to a file called
tip.hs
- open
ghci
at the location of the file - type
:l tip.hs
at the prompt to load the file - type
main
to run the program
Alternatively you can compile it:
- save the code to a file called
tip.hs
- type
ghc --make tip.hs
to compile the program - type
tip.exe
(or./tip
depending on your environment) to run the program
This exercise stretched me further than I had read in either of the tutorials, so I had to scrap around a bit and learn how to do basic IO (monads). So how does it work? Well …
I import the System.IO
library. I didn’t realise this at first, but the input and output were buffered by default and all of the calls to PutStr
were being printed at once which was undesirable, so I’m going to disable buffering for stdout
and stdin
and for that I need System.IO
.
I define a function called main
that executes a sequence of actions in a do
block. I disable buffering for stdout
and stdin
as previously mentioned. The program prompts for the bill amount and the tip rate and stores the input. I use read
to convert the input from a String
to a Float
. Then I calculate the tip and the total and write them out to the console using ++
to concatenate and show
to convert the Float
value to a String
.
It’s a bit rough, I admit it. There are no constraints or error checking on the input, read
will throw an exception if the input String
can’t be parsed to a Float
. Strange things might happen if the Float
calculation overflows. I don’t print the values out with 2 decimal places, and there’s nothing particularly functional about any of it, but that right there is my first Haskell program, I learned a bunch of new things and I’m a little chuffed!