James Bowen James Bowen

Function Application: Using the Dollar Sign ($)

Things have been a little quiet here on the blog lately. We've got a lot of different projects going on behind the scenes, and we'll be making some big announcements about those soon! If you want to stay up to date with the latest news, make sure you subscribe to our mailing list! You'll get access to our subscriber-only resources, including our Beginners Checklist and our Production Checklist!

The next few posts will include a video as well as a written version! So you can click the play button below, or scroll down further to read along!

Let's talk about one of the unsung heroes, a true foot soldier of the Haskell language: the function application operator, ($). I used this operator a lot for a long time without really understanding it. Let's look at its type signature and implementation:

infixr 0
($) :: (a -> b) -> a -> b
f $ a = f a

For the longest time, I treated this operator as though it were a syntactic trick, and didn't even really think about it having a type signature. And when we look at this signature, it seems really basic. Quite simply, it takes a function, and an input to that function, and applies the function.

At first glance, this seems totally unnecessary! Why not just do "normal" function application by placing the argument next to the function?

add5 :: Int -> Int
add5 = (+) 5

-- Function application operator
eleven = add5 $ 6

-- Same result as "Normal" function application
eleven' = add5 6

This operator doesn't let us write any function we couldn't write without it. But it does offer us some opportunities to organize our code a bit differently. And in some cases this is cleaner and it is more clear what is going semantically.

Grouping with $

Because its precedence is so low (level 0) this operator can let us do some kind of rudimentary grouping. This example doesn't compile, because Haskell tries to treat add5 as the second input to (+), rather than grouping it with 6, which appears to be its argument.

-- Doesn't compile!
value = (+) 11 add5 6

We can group these together using parentheses. But the low precedence of ($) also allows it to act as a "separator". We break our expression into two groups. First we add and apply the first argument, and then we apply this function with the result of add5 6.

-- These work by grouping in different ways!

value = (+) 11 $ add5 6

value' = (+) 11 (add5 6)

Other operators and function applications bind more tightly, so can have expressions like this:

value = (+) 11 $ 6 + 7 * 11 - 4

A line with one $ essentially says "get the result of everything to the right and apply it as one final argument". So we calculate the result on the right (79) and then perform (+) 11 with that result.

Reordering Operations

The order of application also reverses with the function application operator as compared to normal function application. Let's consider this basic multiplication:

value = (*) 23 15

Normal function application orders the precedence from left-to-right. So we apply the argument 23 to the function (*), and then apply the argument 15 to the resulting function.

However, we'll get an error if we use $ in between the elements of this expression!

-- Fails!
value = (*) $ 23 $ 15

This is because ($) orders from right-to-left. So it first tries to treat "23" as a function and apply "15" as its argument.

If you have a chain of $ operations, the furthest right expression should be a single value. Then each grouping to the left should be a function taking a single argument. Here's how we might make an example with three sections.

value = (*) 23 $ (+10) $ 2 + 3

Higher Order Functions

Having an operator for function application also makes it convenient to use it with higher order functions. Let's suppose we're zipping together a list of functions with a list of arguments.

functions = [(+3), (*5), (+2)]

arguments = [2, 5, 7]

The zipWith function is helpful here, but this first approach is a little clunky with a lambda:

results = zipWith (\f a -> f a) functions arguments

But of course, we can just replace that with the function application operator!

results = zipWith ($) functions arguments

results = [5, 25, 9]

So hopefully we know a bit more about the "dollar sign" now, and can use it more intelligently! Remember to subscribe to Monday Morning Haskell! There will be special offers for subscribers in the next few weeks, so you don't want to miss out!

Read More
James Bowen James Bowen

Haskellings Beta!

We spent a few months last year building the groundwork for Haskellings in this YouTube series. Now after some more hard work, we're happy to announce that Haskellings is now available in the beta stage. This program is meant to be an interactive tutorial for learning the Haskell language. If you've never written a line of Haskell in your life, this program is designed to help you take those first steps! You can take a look at the Github repository to learn all the details of using it, but here's a quick overview.

Overview

Haskellings gives you the chance to write Haskell code starting from the very basics with a quick evaluation loop. It currently has 50 different exercises for you to work with. In each exercise, you can read about a Haskell concept, make appropriate modifications, and then run the code with a single command to check your work!

functions_start.png
functions_after.png

You can do exercises individually, but the easiest way to do everything in order is to run the program in Watcher mode. In this mode, it will automatically tell you which exercise is next. It will also re-run each exercise every time you save your work.

watcher.png

Haskellings covers a decent amount of ground on basic language concepts. It starts with the very basics of expressions, types and functions, and goes through the basic usage of monads.

Haskellings is an open source project! If you want to report issues or contribute, learn how by reading this document! So go ahead, give it a try!

Don't Forget: Haskell From Scratch

Haskellings is a quick and easy way to learn the language basics, but it only touches on the surface of a lot of elements. To get a more in-depth look at the language, you should consider our Haskell From Scratch video course. This course includes:

  1. Hours of video lectures explaining core language concepts and syntax
  2. Dozens of practice problems to help you hone your skills
  3. Access to our Slack channel, so you can get help and have your questions answered
  4. A final mini-project, to help you put the pieces together

This course will help you build a rock-solid foundation for your future Haskell learnings. And even better, we've now cut the price in half! So don't miss out!

Read More
James Bowen James Bowen

Advanced Series Updated!

newlogo3transparent.png

We're back again with some more site improvements, this time to our Advanced Content. All of these series now have improved syntax highlighting and code blocks for better readability. In addition, we've revised three of them with updated companion code! Here's a summary.

Real World Haskell Series

Once you've mastered the foundations of the language, this series should be your first stop! It will walk you through several different libraries demonstrating how you can perform some real-world tasks with Haskell, like connecting to a database and running a web server. You can follow along with all the code here on GitHub.

Parsing Series

As a functional language, Haskell thrives on being able to seemlessly compose smaller pieces of code together into a large, coherent whole. Parsing libraries are one area where this paradigm fits very well. In this series, we go through a few different parsing libraries and compare them. The code is available in this repository if you want to try it out yourself!

API Integrations Series

A lot of coding projects involved connected with outside services and APIs. Luckily, Haskell has a few libraries for interacting with these services! In this series, we'll explore integrations with Twilio and Mailgun so that we can send text messages and emails to your users! You can get a detailed breakdown of the code on GitHub. You can even fork the repository and run the code for yourself!

What's Coming Up?

Our next area of focus will be working on a first release of Haskellings, an interactive beginner tutorial for the language. We built this over the course of the last few months of 2020 in an extended video series that you can catch here on YouTube. The project is Open Source and currently available for contributions! Stay tuned for more updates on it!

Read More
James Bowen James Bowen

Beginners Series Updated!

newlogo3transparent.png

Where has Monday Morning Haskell been? Well, to ring in 2021, we've been making some big improvements to the permanent content on the site. So far we've focused on the Beginners section of the site. All the series here are updated with improved code blocks and syntax highlighting. In addition, we've fully revised most of them and added companion Github repositories so you can follow along!

Liftoff

Our Liftoff Series is our first stop for Haskell beginners. If you've never written a line of Haskell in your life but want to learn, this is the place to start! You can follow along with all the code in the series by using this Github repository.

Monads Series

Monads are a big "barrier" topic in Haskell. They don't really exist much in most other languages, but they're super important in Haskell. Our Monads Series breaks them down, starting with simpler functional structures so you can understand more easily! The code for this series can be found on Github here.

Testing Basics

You can't do serious production development in any language until you've mastered the basics of unit testing. Our Testing Series will school you on the basics of writing and running your first unit tests in Haskell. It'll also teach you about profiling your code so you can see improvements in its runtime! And you can follow along with the code right here on Github!

Haskell Data Basics

Haskell's data types are one of the first things that made me enjoy Haskell more than other languages. In this series we explore the ins and outs of Haskell's data declaration syntax and related topics like typeclasses. We compare it side-by-side with other languages and see how much easier it is to express certain concepts! Take a look at the code here!

What's Next?

Next up we'll be going through the same process for some of our more advanced series. So in the next couple weeks you can look forward to improvements there! Stay tuned!

Read More
James Bowen James Bowen

Countdown to 2021!

fireworks.jpg

At last. 2020 is nearly over. It's been a tumultuous year for the entire world, and I think most of us are glad to be turning over a new page, even if the future is still uncertain. As I always do, I'll sign off the year with a review of the different concepts we've looked at this year, and give a preview of what to expect in 2021.

2020 In Review

There were three major themes we covered this year. For much of the start of this year, we focused on AI. The main product of this was our work on a Haskell version of Open AI Gym. We explored ways to generalize the idea of an AI agent, including cool integrations of Haskell ideas like type families. We even wrote this in such a way that we could incorporate Tensor Flow! You can read about that work in our Open AI Series.

Over the summer, we switched gears a bit and focused on Rust. In our Rust Web Series we solved some more interesting problems to parallel our Real World Haskell Series. This included building a simple web server and connecting to a database.

Then our final work area was on our Haskellings program. Modeled after Rustlings, this is intended to be an automated beginner tutorial for the Haskell language. For the first time, I changed up the content a bit and did a video series, rather than a written blog series. So you can find the videos for that series on our YouTube Channel!

We're looking for people to contribute exercises (and possibly other code) to the Haskellings project, so definitely visit the repository if you'd like to help!

Looking Forward

There will be some big changes to the blog in 2021. Here are some of the highlights I'm looking forward to:

Spending more time on how Haskell fits into the broader programming ecosystem and what role it can play for those new to the industry. What can beginning programmers learn from the Haskell language and toolchain? What lessons of Haskell are applicable across many different languages? More exploration of different content types and media. As mentioned above, I spent the last part of 2020 experimenting with video blogs. I expect to do more of this type of experimenting this year. Upgrading the site's appearance and organization. Things have been pretty stagnant for a while, and there are a lot of improvements I'd like to make. For one example, I'd like to make coding sections more clear and interactive in blog posts. New, lighter-weight course material. Right now, our course page has 2 rather large courses. This year I'm going to look at breaking the material in these out into smaller, more manageable chunks, as well as adding a couple totally new course offerings at this smaller size.

I've set a lot of these goals before and fallen short. Unfortunately, I've found that these priorities often get pushed aside due to my desire to publish new content weekly, as I've been doing for over 4 years now (how time flies!). But starting in 2021, I'm going to focus on quality over quantity. I do not plan on publishing every week, and a lot of the blogs I do publish will highlight improvements to old content, rather than being new, detailed technical tutorials. I hope these changes will take the most important content on the blog and make it much more useful to the intended audiences.

I also have a tendency of creating projects to demonstrate concepts, but leave the projects behind once I am done writing about those concepts. This year, I hope to take a couple of my projects, specifically Open AI Gym and the Haskellings Beginner Tutorial and turn them into polished products that other developers will want to use. This will take a lot of focused time and effort, but I think it will be worth it.

So even though you might not see a new post every Monday, never fear! Monday Morning Haskell is here to stay! I hope all of you have a happy and safe new year!

Read More
James Bowen James Bowen

Open Sourcing Haskellings!

newlogo3 (3).png

In the last couple months we've been working on "Haskellings", an automated Haskell tutorial inspired by Rustlings. This week, I'm happy to announce that this project is now open source! You can find the (very early) version here on Github. I'll be working on making the project more complete throughout 2021, but I would really value any contributions the community has to this project! In this article, I'll list a few specific areas that would be good to work on!

More Exercises

The first and most important thing is that we need more exercises! I've done a couple simple examples to get started, but I'd like to crowd-source the creation of exercises. You can use the set of Rustlings exercises as some sort of inspiration. The most important topics to start out with would be things that explain the Haskell type system, so the different sorts of types, expressions and functions, as well as making our own data types. Other good concepts include things like syntax elements (think "where" and "case") and type classes.

Operating System Compatibility

I've definitely cut a few corners when it comes to the MVP of this project. I've only been working on Linux, so it's quite possible that there are some Linux-specific assumptions in the file-system level code. There will need to be some testing of the application on Windows and Mac platforms, and some adjustments will likely be necessary.

GHC Precision

Another area that will need some attention is the configuration section. Is there a cleaner way to determine where the GHC executable lives? What about finding the package database that corresponds to our Stack snapshot? My knowledge of Stack and package systems is limited, so it's very likely that there are some edge cases where the logic doesn't work out.

Exercise Cleanup

Right now, we list all the exercises explicitly in the ExerciseList module. But they're listed in two different places in the file. It would be good to clean this up, and potentially even add a feature for automated detection of exercise features. For example, we can figure out the filename, the directory, and whether or not it's runnable just by examining the file at its path! Right now the only thing that would need to be specified in "code" would be the order of exercises and their hints.

Contributing

If you're interested in contributing to this project, you can fork the repository, put up a pull request, and email me at james@mondaymorninghaskell.me! I'll be working on this periodically throughout 2021, hoping to have a more complete version to publish by the end.

Read More
James Bowen James Bowen

Dependencies and Package Databases

Here's the final video in our Haskellings series! We'll figure out how to add dependencies to our exercises. This is a bit trickier than it looks, since we're running GHC outside of the Stack context. But with a little intuition, we can find where Stack is storing its package database and use that when running the exercise!

Next week, we'll do a quick summary of our work on this program, and see what the future holds for it!

Read More
James Bowen James Bowen

Adding Hints

If a user is struggling with a particular exercise, we don't want them to get stuck! In this week's video, we'll see how to add "hints" to the Watcher. This way, a user can get a little extra help when they need it! We can also use this functionality to add more features in the future, like skipping an exercise, or even asking the user questions as part of the exercise!

Read More
James Bowen James Bowen

Executing Executables!

In Haskell, we'd like to think "If it compiles, it works!" But of course this isn't generally the case. So in addition to testing whether or not our exercises compile, we'll also want to run the code the user wrote and see if it works properly! In this week's video, we'll see how we can distinguish between these two different exercise types!

Read More
James Bowen James Bowen

Testing the Watcher

In our Haskellings program, the Watcher is a complex piece of functionality. It has to track changes to particular files, re-compile them on the spot, and keep track of the order in which these exercises should be done. So naturally, writing unit tests for it presents challenges as well! In this video, we'll explore how to simulate file modifications in the middle of a unit test.

Read More
James Bowen James Bowen

Unit Testing Compilation

We've used Hspec before on the blog. But now we'll apply it to our Haskellings program, in conjunction with the program configuration changes we made last week! We'll write a couple simple unit tests that will test the basic compilation behavior of our program. Check out the video to see how!

Read More
James Bowen James Bowen

Using the Handle Abstraction

Our haskellings program is starting to get a bit more complicated, so it would be nice to write some unit tests for it. But this is very difficult to do for a command line application! To set this up, we'll start by refactoring our program to use the Handle abstraction. This allows the program to work regardless of whether it's using the command line or file for its input. So the user will see the command line version, but our tests will be able to use files! We'll also use the process of Compile Driven Development to systematically refactor our program to use these new configuration elements!

Read More
James Bowen James Bowen

Sequencing Exercises in the Watcher

Our watcher program can keep tabs on our exercise files, but it doesn't have any notion of an exercise order. In this week's video, we'll fix this! Our watcher will focus on one specific "current" exercise. When we're done with that, it will move us on to the next one automatically! This video involves a good example of using recursion in our Haskell workflow. But even better, we'll see a rudimentary usage of an MVar to pass information between the threads of our program. Take a look!

Read More
James Bowen James Bowen

Overriding Process Handlings and Terminal Colors

Right now, our Haskellings program doesn't give the user any information or output aside from the actual compilation stream. For this week's video blog, we'll dig in a bit deeper to the process to give the user better information. We'll use the process's exit information and override its handles to control which output the user sees and when. Then as a final flourish, we'll color the user's terminal output result to be more helpful!

Read More
James Bowen James Bowen

Watching Files with FS-Notify!

This week we continue laying out the groundwork for our "Haskellings" project. A key part of the this program is the automated aspect of "watch" mode. A user should be able to modify their file and then immediately see the results of their changes in the watcher window. This week, we get familiar with the fsnotify package, which lets us watch files and directories and take actions in our program when they change!

Read More
James Bowen James Bowen

Haskellings 2: Better Configuration

This week we'll continue working on our nascent Haskellings project. There's a few interesting things we'll learn here around using the directory package. We'll also explore how to use the Seq data structure to implement a quick Bread-First-Search algorithm!

Read More
James Bowen James Bowen

Starting Haskellings!

After learning about the Rustlings program in the last few weeks, we're now going to try to start replicating it in Haskell! In this week's video blog, we'll learn a little bit about using the ghc command on its own outside of Stack/Cabal, and then how to run it from within our program using the System.Process library.

Read More
James Bowen James Bowen

Rustlings Part 2

This week we continue with another Rustlings video tutorial! We'll tackle some more advanced concepts like move semantics, traits, and generics! Next week, we'll start considering how we might build a similar program to teach beginners about Haskell!

Read More
James Bowen James Bowen

Rustlings Video Blog!

We're doing something very new this week. Instead of doing a code writeup, I've actually made . In keeping with the last couple months on content, this first one is still Rust related. We'll walkthrough the Rustlings tool, which is an interactive program that teaches you the basics of the Rust Language! Soon, we'll start exploring how we might do this in Haskell!

You can also watch this video on our YouTube Channel! Subscribe there or sign up for our mailing list!

Read More
James Bowen James Bowen

Rust Web Series Complete!

rust_web.jpg

We're taking a quick breather this week from new content for an announcement. Our recently concluded Rust Web series now has a permanent spot on the advanced page of our website. You can take a look at the series page here! Here's a quick summary of the series:

  1. Part 1: Postgres - In the first part, we learn about a basic library to enable integration with a Postgresql Database.
  2. Part 2: Diesel - Next up, we get a little more formal with our database mechanics. We use the Diesel library to provide a schema for our database application.
  3. Part 3: Rocket - In part 3, we take the next step and start making a web server! We'll learn the basics of the Rocket server library!
  4. Part 4: CRUD Server - What do we do once we have a database and server library? Combine them of course! In this part, we'll make a CRUD server that can access our database elements using Diesel and Rocket.
  5. Part 5: Authentication - If your server will actually serve real users, you'll need authentication at some point. We'll see the different mechanisms we can use with Rocket for securing our endpoints.
  6. Part 6: Front-end Templating - If you're serving a full front-end web app, you'll need some way to customize the HTML. In the last part of the series, we'll see how Rocket makes this easy!

The best part is that you can find all the code for the series on our Github Repo! So be sure to take a look there. And if you're still new to Rust, you can also get your feet wet first with our Beginners Series.

In other exciting news, we'll be trying a completely new kind of content in the next couple weeks. I've written a bit in the past about using different IDEs like Atom and IntelliJ to write Haskell. I'd like to revisit these ideas to give a clearer idea of how to make our lives easier when writing code. But instead of writing articles, I'll be making a few videos to showcase how these work! I hope that a visual display of the IDEs will help make the content more clear.

Read More