Using (Functors, Applicatives, and) Monads

Due Wednesday, Sept 18th @ 9 am

From this assignment, students will show...

Functional Programming - Recall

through function definition and implementation.

CodeGen and Metaprogramming - Recall

through applying the lessons of code reuse from typeclasses to the three of the most common design patterns in haskell.

Metacognition, Reflection, and Personal Growth - Requisite

through answering the reflection questions in the META.md.

Note: For recall learning objectives, please tell me what skill you had to apply again and where it was originally applied.

A visual aid

I found this explination to be fun and helpful. Feel free to consult it if you get stuck.

Let's begin

  1. Pull the latest Exemplars Github Repo
  2. Follow the instructions in src/Lib.hs by completing all the tasks marked in the comments (e.g. -- 1) ...).
  3. Answer the following reflection questions and add them to your META.md
  4. Finish the usual material for your META.md

Step-by-step instruction

Looking ahead, you will be designing a domain specific language for some programming domain of your choice. First, you will put on the hat of a programmer in that domain. You will write programs in the domain using bare haskell abstractions and design patterns.

Also, the tools we will be using to write the metaprograms themselves are used using bare haskell abstractions and design patterns. Specifically, monads are the design pattern that we saw in the Template Haskell paper (the Q Monad) to sequence compilation, and monads will be the design pattern we use to implement our parsers (the Parsec Monad) to sequence parsing a string.

There are many ways to teach these design patterns, and some are more helpful than others for particular people. Below is a bottom up approach that Matthew used to learn them that starts with something you are familiar with (map functions) and works through increasing levels of abstractions until we arrive at monads.

This method of learning monads might not work for everyone, and so the next homeworks will provide a top-down approach to learning monads. You will learn by doing in the template haskell domain and the parsec domain. So, if at any point you feel that this homework isn't helping you learn or apply the design patterns. Stop! You will be able to achieve the same learning objectives on the next assignments

This video series is available as a youtube playlist

The following video series aims to provide some muscle memory building up to Monads. For a data structure (some type :: * -> * ) to be a Monad, it must also be an Applicative. And in turn, all Applicatives must be Functors. So, starting with functionality you are used to, map, we will be playing with the instances of these design patterns for common data structures.

The main idea from this homework is when defining a data structure, designers implement the typeclasses for Functors, Applicatives, and Monads to prescribe how to connect computations over the data structure together.

Functors - mapping over datastructures

Many libraries for domain specific programming in Haskell will simply export an api as a collection of functions. One of the first ways to use these apis is to weave them through the data structures in your programs. So, in this video, you will gain some practice with Functors, the design pattern for describing how to map an arbitrary function over values in a data structure.

Applicatives - applying a wrapped function over datastructures

Often, we will partially apply a library function over our data structures. When we partially apply a function, we get a function back. When we map it over our data structure we must then get a function wrapped in that data structure. So, we need the data datastucture to tell us what that means. Specifically, applying a function wrapped in a Maybe (e.g. Maybe (Int -> String)) might be very different than a list of functions (e.g. [Int -> String]). So, because we often encounter the pattern of applying wrapped functions, we use the applicative typeclass to describe the data structures that can apply functions held within. In this video, you will be playing some instances of the Applicative typeclass.

Monads - binding together data constructors

You are familiar with algebraic data types whose data constructors are public. Just, Left, Right, Cons, Tuple syntax, etc. are all data constructors and patterns that construct and deconstruct data structures. When we want to compute over multiple uses of a constructor, we often use case statements or functions to apply the constructor, unpack the data, do the computation, and repack the result. For many data constructors, the act of unpacking and repacking the data is the same, and it doesn't matter what the data is. This design pattern is represented as the Monad typeclass. In this video, you will be implementing two data constructors and chaining them together either using >>= or do-notation.

Tip: Constructing lists over a pattern of numbers has a handy syntax

Monads - Abstractly defined datatypes

Often, designers hide the internals of their data structures so that users cannot get into a bad state. But, in order to still be usable, they need to expose a way for computations to be chained together. Two of the data structures that hide their internals you will commonly encounter are State and IO. Both of these data constructors instantiate the Monad typeclass to describe how side effecting actions are sequenced. Users compose bigger side-effecting computations out of the primitives by the Monad methods. In this video, you will use the primitives for these data structures, and the monad methods (either >>= or do-notation) practice sequenced, side-effecting computation.

I'm here but I still have questions (even if I don't know what they are)!

It's completely understandable and expected to still have questions at this point. Steps you can take to help unstick yourself: I hope you feel comfortable reaching out even if you cannot formulate your questions.

META.md

META.md should include
  1. your name
  2. your utln
  3. how much time you spent on this assignment
  4. the witness "proof" for how you earned each learning objective with a note about recall for recall objectives
  5. answers to the reflection questions

Please Submit

Contents to be submitted

Method of submission

Please commit your changes in the hw04-1 directory of your private repo and push them to the remote server before 9 am.