Monads. Prof. Clarkson Fall Today s music: Vámanos Pal Monte by Eddie Palmieri

Similar documents
Modular Programming. Prof. Clarkson Fall Today s music: "Giorgio By Moroder" by Daft Punk

Async. Prof. Clarkson Fall Today s music: It's Gonna be Me by *NSYNC

CSCE 314 Programming Languages Functors, Applicatives, and Monads

Futures. Prof. Clarkson Fall Today s music: It's Gonna be Me by *NSYNC

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

Some Advanced ML Features

Verification in Coq. Prof. Clarkson Fall Today s music: Check Yo Self by Ice Cube

Formal Semantics. Prof. Clarkson Fall Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

Last time: generic programming

Specifications. Prof. Clarkson Fall Today s music: Nice to know you by Incubus

Mutable Data Types. Prof. Clarkson Fall A New Despair Mutability Strikes Back Return of Imperative Programming

Monad Overview (3B) Young Won Lim 1/16/18

The Substitution Model

Data Types. Prof. Clarkson Fall Today s music: Pokémon Theme by Jason Paige

1 Delimited continuations in Haskell

CMSC 430 Introduction to Compilers. Fall Everything (else) you always wanted to know about OCaml (but were afraid to ask)

Modular implicits for OCaml how to assert success. Gallium Seminar,

The List Datatype. CSc 372. Comparative Programming Languages. 6 : Haskell Lists. Department of Computer Science University of Arizona

Abstraction Functions and Representation Invariants

CS Prof. Clarkson Fall 2014

Fall Lecture 3 September 4. Stephen Brookes

Amortized Analysis. Prof. Clarkson Fall Today s music: : "Money, Money, Money" by ABBA

Abstraction and Specification

Programming Languages and Techniques (CIS120)

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

Two approaches to writing interfaces

Background Type Classes (1B) Young Won Lim 6/14/18

CS 11 Haskell track: lecture 4. n This week: Monads!

Applicative, traversable, foldable

Type Inference. Prof. Clarkson Fall Today s music: Cool, Calm, and Collected by The Rolling Stones

Lecture 4: Higher Order Functions

Applicative, traversable, foldable

Informatics 1 Functional Programming 19 Tuesday 23 November IO and Monads. Philip Wadler University of Edinburgh

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

CSE341 Spring 2016, Midterm Examination April 29, 2016

Data Types. Guest Lecture: Andrew Myers Spring 2018

JVM ByteCode Interpreter

CMSC 330: Organization of Programming Languages. Objects and Abstract Data Types

Modules and Representation Invariants

Haskell. COS 326 Andrew W. Appel Princeton University. a lazy, purely functional language. slides copyright David Walker and Andrew W.

Monads seen so far: IO vs Gen

Maybe Monad (3B) Young Won Lim 1/3/18

Programming Languages

Staging (part II) March 2018

EECS 700 Functional Programming

College Functors, Applicatives

CS153: Compilers Lecture 15: Local Optimization

05-15/17 Discussion Notes

Advanced Type System Features Tom Schrijvers. Leuven Haskell User Group

Lists. Michael P. Fourman. February 2, 2010

Balanced Trees. Prof. Clarkson Fall Today s music: Get the Balance Right by Depeche Mode

Introduction to Haskell

A Fourth Look At ML. Chapter Eleven Modern Programming Languages, 2nd ed. 1

Monads and all that I. Monads. John Hughes Chalmers University/Quviq AB

CS 11 Ocaml track: lecture 4. Today: modules

CSE 341 : Programming Languages Midterm, Spring 2015

TYPE INFERENCE. François Pottier. The Programming Languages Mentoring ICFP August 30, 2015

Programming with Math and Logic

CS Lecture 6: Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Name: CIS 120e Midterm I Review

Maybe Monad (3B) Young Won Lim 12/21/17

Objects. Prof. Clarkson Fall ob-ject: to feel distaste for something Webster's Dictionary. Today s music: Kung Fu Fighting by CeeLo Green

CSE341 Spring 2016, Midterm Examination April 29, 2016

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

Programovací jazyky F# a OCaml. Chapter 5. Hiding recursion using function-as-values

Monads in Haskell. Nathanael Schilling. December 12, 2014

Defining Functions. CSc 372. Comparative Programming Languages. 5 : Haskell Function Definitions. Department of Computer Science University of Arizona

The Worker/Wrapper Transformation

CSci 4223 Principles of Programming Languages

CS Lecture 14: Hash tables. Prof. Clarkson Spring Today s music: Re-hash by Gorillaz

CMSC 330: Organization of Programming Languages

Lecture 21: Red-Black Trees

Behavioral Equivalence

Haskell Monads CSC 131. Kim Bruce

Functional Programming. Lecture 2: Algebra

First-class modules: hidden power and tantalizing promises

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Polymorphism Overview (1A) Young Won Lim 2/20/18

Behavioral Equivalence

Programming Languages and Techniques (CIS120)

ob-ject: to feel distaste for something Webster's Dictionary

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

Advanced Programming Handout 7. Monads and Friends (SOE Chapter 18)

Advanced Functional Programming

First-Class Type Classes

CSE341 Autumn 2017, Midterm Examination October 30, 2017

Functions. Nate Foster Spring 2018

Monads. Lecture 12. Prof. Aiken CS 264 Lecture 12 1

Accurate Step Counting

Parametric types. map: ( a (a b) a list b list. filter: ( a bool) a list a list. Why? a and b are type variables!

Haskell Introduction Lists Other Structures Data Structures. Haskell Introduction. Mark Snyder

Error Processing: An Exercise in Functional Design

A Functional Evaluation Model

Title: Recursion and Higher Order Functions

OCaml Language Choices CMSC 330: Organization of Programming Languages

I/O in Purely Functional Languages. Stream-Based I/O. Continuation-Based I/O. Monads

Programming in Haskell Aug-Nov 2015

Interpreters. Prof. Clarkson Fall Today s music: Step by Step by New Kids on the Block

GADTs. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 7. [Faculty of Science Information and Computing Sciences]

Transcription:

Monads Prof. Clarkson Fall 2017 Today s music: Vámanos Pal Monte by Eddie Palmieri

Review Currently in 3110: Advanced topics Futures: Async: deferreds, return, bind Today: Monads

Monad tutorials since 2011: another 34 at least source: https://wiki.haskell.org/monad_tutorials_timeline

Question Have you programmed with monads in Haskell? A. No B. Yes C. Yes, and I've written a monad tutorial

Monad tutorials "A monad is a monoid object in a category of endofunctors...it might be helpful to see a monad as a lax functor from a terminal bicategory."

Monad tutorials "A monad is a monoid object in a category of endofunctors...it might be helpful to see a monad as a lax functor from a terminal bicategory."

Monad tutorials "A monad is a monoid object in a category of endofunctors...it might be helpful to see a monad as a lax functor from a terminal bicategory." "Monads are burritos." [http://chrisdone.com/posts/monads-are-burritos]

Monad For our purposes: module type Monad = sig type 'a t val bind : 'a t -> ('a -> 'b t) -> 'b t val return : 'a -> 'a t end Any structure that implements the Monad signature is a monad. What's the big deal???

LOGGABLE FUNCTIONS

Loggable functions Suppose you're implementing two functions: f: int -> int g: int -> int And you'd like to compute their composition: let h x = g (f x) (* = x > f > g *) let (>>) f g x = x > f > g let h x = (f >> g) x let h = f >> g

Loggable functions You d like also log some additional information each time function is called: f_log: int -> int * string g_log: int -> int * string

Loggable functions let inc x = x+1 let dec x = x-1 let id = inc >> dec let inc_log x = (x+1, "incremented " ^ string_of_int x ^ "; ") let dec_log x = (x-1, "decremented " ^ string_of_int x ^ "; ") (* let id_log = inc_log >> dec_log *) Q: Why doesn t that work? A: dec_log takes an int as input not an int * string

Loggable functions let id_log x = let (y,s1) = inc_log x in let (z,s2) = dec_log y in (z,s1^s2) Critique: Hard to infer from that code that it's doing composition! Ugly and verbose compared to let id_log = inc_log >> dec_log

Upgrading a function What if we could upgrade a loggable function to accept the input from another loggable function? upgrade f_log : int*string -> int*string

Upgrading a function let upgrade f_log (x,s1) = let (y,s2) = f_log x in (y,s1^s2) let id_log = inc_log >> upgrade dec_log Nice separation of concerns! upgrade handles the "plumbing" with the strings the definition of id_log is clearly about composition

Another kind of upgrade Given f : int -> int How to make it loggable, but with empty log message? Need to "lift" a function from int -> int to int -> int*string That's easy: let trivial x = (x, "") let lift f = f >> trivial

Types Consider the types: val upgrade : (int -> int * string) -> int * string -> int * string val trivial : int -> (int * string)

Types Another way of writing those types: type 'a t = 'a * string val upgrade : (int -> int t) -> int t -> int t val trivial : int -> int t

Types Let s swap the argument order of upgrade... val upgrade : (int -> int t) -> int t -> int t let upgrade' x f = upgrade f x val upgrade : int t -> (int -> int t) -> int t

Types type 'a t = 'a * string val upgrade' : int t -> (int -> int t) -> int t val trivial : int -> int t Have you seen those types before?

Rewriting types type 'a t = 'a * string val bind : int t -> (int -> int t) -> int t val return : int -> int t module type Monad = sig type 'a t val bind : 'a t -> ('a -> 'b t) -> 'b t val return : 'a -> 'a t end

Loggable is a monad module Loggable : Monad = struct type 'a t = 'a * string let bind (x,s1) f = let (y,s2) = f x in (y,s1^s2) let return x = (x,"") end More often called the writer monad

Stepping back... We took functions We made them compute something more A logging string We invented ways to pipeline them together upgrade, trivial We discovered those ways correspond to the Monad signature

FUNCTIONS THAT PRODUCE ERRORS

Functions and errors A4: you implemented an interpreter Results could be either values or exceptions So evaluation produced a variant with constructor for either possibility A partial function (in math) is undefined for some inputs e.g., max_list : int list -> int with that type, programmer probably intends to raise an exception on the empty list could also produce an option or like A4, could use variant to encode result

A type for possible errors type 'a t = Val of 'a Err let div (x:int) (y:int) = if y=0 then Err else Val (x / y) let neg (x:int) = Val (-x)

Error handling Lifting those function to handle inputs that might be errors... let neg_err = function Err -> Err Val x -> Val (-x) let div_err x y = match (x,y) with (Err,_) (_,Err) -> Err (Val a,val b) -> if b=0 then Err else Val (a/b) And any other functions you write have to pattern match to handle errors... Could we get rid of all that boilerplate pattern matching?

Eliminating boilerplate matching (* [rev_app_err m f] applies f * to m, like [x > f], but * handling Err as necessary. *) let rev_app_err m f = match m with Val x -> f x Err -> Err let ( >?) = rev_app_err

Eliminating boilerplate matching let neg_err = function Err -> Err Val x -> Val (-x) let neg_err x = x >? (fun a -> Val (-a))

Eliminating boilerplate matching let div_err x y = match (x,y) with (Err,_) (_,Err) -> Err (Val a,val b) -> if b=0 then Err else Val (a/b) let div_err x y = x >? fun a -> y >? fun b -> if b=0 then Err else Val (a/b)

Another way to write that code let value x = Val x let neg_err x = x >? fun a -> value (-a) let div_err x y = x >? fun a -> y >? fun b -> if b=0 then Err else value (a/b)

What are the types? type 'a t = Val of 'a Err val value : 'a -> 'a t val ( >?) : 'a t -> ('a -> 'b t) -> 'b t Have you seen those types before??? module type Monad = sig type 'a t val bind : 'a t -> ('a -> 'b t) -> 'b t val return : 'a -> 'a t end

Error is a monad module Error : Monad = struct type 'a t = Val of 'a Err let return x = Val x let bind m f = match m with Val x -> f x Err -> Err end

Option is a monad module Option : Monad = struct type 'a t = Some of 'a None let return x = Some x let bind m f = match m with Some x -> f x None -> None end

Stepping back... We took functions We made them compute something more A value or possibly an error We invented ways to pipeline them together value, ( >?) We discovered those ways correspond to the Monad signature

ASYNC

Deferred is a monad module Deferred : sig type 'a t val return : 'a -> 'a t val bind : 'a t -> ('a -> 'b t) -> 'b t end return takes a value and returns an immediately determined deferred bind takes a deferred, and a function from a non-deferred to a deferred, and returns a deferred that result from applying the function

Stepping back... We took functions The Async library made them compute something more a deferred result The Async library invented ways to pipeline them together return, (>>=) Those ways correspond to the Monad signature So we call Async a monadic concurrency library

Another view of Monad module type Monad = sig (* a "boxed" value of type 'a *) type 'a t (* [m >>= f] unboxes m, * passes the result to f, * which computes a new result, * and returns the boxed new result *) val (>>=) : 'a t -> ('a -> 'b t) -> 'b t (* box up a value *) val return : 'a -> 'a t end (equate "box" with "tortilla" and you have the burrito metaphor)

SO WHAT IS A MONAD?

Computations A function maps an input to an output A computation does that and more: it has some effect Loggable computation: effect is a string produced for logging Error computation: effect is a possible error instead of a value Option computation: effect is a possible None instead of a value Deferred computation: effect is delaying production of value until scheduler makes it happen A monad is a data type for computations return has the trivial effect (>>=) does the "plumbing" between effects

Phil Wadler A designer of Haskell Wrote the paper* on using monads for functional programming b. 1956 * http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf

Other monads State: modifying the state is an effect List: producing a list of values instead of a single value can be seen as an effect Random: producing a random value can be seen as an effect...

Monad laws As you've seen in Coq, data types must obey some algebraic laws e.g., for stacks, peek (push x s) = x We don't write them in OCaml types, but they're essential for expected behavior Monads must obey these laws: 1. return x >>= f is equivalent to f x 2. m >>= return is equivalent to m 3. (m >>= f) >>= g is equivalent to m >>= (fun x -> f x >>= g) Why? The laws make sequencing of effects work the way you expect

Monad laws 1. (return x >>= f) = f x Doing the trivial effect then doing a computation f is the same as just doing the computation f (return is left identity of bind) 2. (m >>= return) = m Doing only a trivial effect is the same as not doing any effect (return is right identity of bind) 3. ((m >>= f) >>= g) = (m >>= (fun x -> f x >>= g)) Doing f then doing g as two separate computations is the same as doing a single computation which is f followed by g (bind is associative)

Upcoming events Happy Thanksgiving Break! [Wed and Thur] no class [Mon] recitations do meet This is effectful. THIS IS 3110