Applicatives Comparisons (2C) Young Won Lim 3/6/18

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

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

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

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

Side Effects (3A) Young Won Lim 1/13/18

Side Effects (3B) Young Won Lim 11/20/17

Side Effects (3B) Young Won Lim 11/23/17

Side Effects (3B) Young Won Lim 11/27/17

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

Monad Background (3A) Young Won Lim 11/18/17

Monad Background (3A) Young Won Lim 11/8/17

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

Background Operators (1E) Young Won Lim 7/7/18

CSCE 314 Programming Languages Functors, Applicatives, and Monads

Monad Background (3A) Young Won Lim 11/20/17

Monad (1A) Young Won Lim 6/26/17

State Monad (3D) Young Won Lim 8/31/17

Monad (1A) Young Won Lim 6/9/17

Monads. Bonus lecture 2017 David Sands

IO Monad (3D) Young Won Lim 1/18/18

Monad (3A) Young Won Lim 8/9/17

Libraries (1A) Young Won Lim 6/5/17

CIS 194: Homework 6. Due Friday, October 17, Preface. Setup. Generics. No template file is provided for this homework.

GHCi: Getting started (1A) Young Won Lim 6/3/17

Background Functions (1C) Young Won Lim 5/26/18

Monad P1 : Several Monad Types (4A) Young Won Lim 2/13/19

IO Monad (3C) Young Won Lim 1/6/18

Monad Background (3A) Young Won Lim 10/5/17

Monoid (4A) Young Won Lim 8/12/17

Monad (1A) Young Won Lim 6/21/17

State Monad Examples (6C) Young Won Lim 9/26/18

Logic Haskell Exercises

State Monad Example (3H) Young Won Lim 2/16/18

IO Monad (3C) Young Won Lim 8/23/17

Programming with Math and Logic

State Monad Examples (6C) Young Won Lim 9/22/18

GHCi: Getting started (1A) Young Won Lim 5/31/17

Binary Search Tree (2A) Young Won Lim 5/17/18

State Monad (3D) Young Won Lim 9/25/17

GHCi: Getting started (1A) Young Won Lim 5/26/17

More on functional programming

Haskell Overview IV (4A) Young Won Lim 10/24/16

College Functors, Applicatives

Programming in Haskell Aug Nov 2015

Background Expressions (1D) Young Won Lim 7/7/18

All About Comonads (Part 1) An incomprehensible guide to the theory and practice of comonadic programming in Haskell

Monads and all that III Applicative Functors. John Hughes Chalmers University/Quviq AB

Functions (4A) Young Won Lim 5/8/17

Haskell Overview II (2A) Young Won Lim 8/9/16

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

A Sudoku Solver Pruning (3A)

Monads seen so far: IO vs Gen

Haskell Monads CSC 131. Kim Bruce

Applicative, traversable, foldable

Function Overview (1A) Young Won Lim 10/23/17

Functions (4A) Young Won Lim 3/16/18

Background Constructors (1A) Young Won Lim 7/9/18

Pointers (1A) Young Won Lim 3/5/18

Monads in Haskell. Nathanael Schilling. December 12, 2014

COMP3141 Assignment 2

Arrays (1A) Young Won Lim 12/4/17

Algorithms Bubble Sort (1B) Young Won Lim 4/5/18

Background Constructors (1A) Young Won Lim 6/30/18

Applicative, traversable, foldable

Haskell Overview IV (4A) Young Won Lim 10/13/16

Binary Search Tree (3A) Young Won Lim 6/2/18

Applications of Arrays (1A) Young Won Lim 2/11/17

Haskell Overview II (2A) Young Won Lim 9/26/16

Background Constructors (1A) Young Won Lim 1/22/18

Pointers (1A) Young Won Lim 1/9/18

Pointers (1A) Young Won Lim 1/5/18

Background Constructors (1A) Young Won Lim 7/5/18

Accessibility (1A) Young Won Lim 8/22/13

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

CS 440: Programming Languages and Translators, Spring 2019 Mon 2/4

Operators (2A) Young Won Lim 10/2/13

Background Functions (1C) Young Won Lim 4/3/18

Informatics 1 Functional Programming Lectures 15 and 16. IO and Monads. Don Sannella University of Edinburgh

Type system. Type theory. Haskell type system. EDAN40: Functional Programming Types and Type Classes (revisited)

Applications of Arrays (1A) Young Won Lim 3/15/17

Bringing Functions into the Fold Tom Schrijvers. Leuven Haskell User Group

Pointers (1A) Young Won Lim 11/1/17

Eulerian Cycle (2A) Young Won Lim 4/26/18

1. Function Type Declarations (12 points):

Functional Programming

Haskell Overview II (2A) Young Won Lim 8/23/16

Operators (2A) Young Won Lim 10/5/13

Haskell Overview III (3A) Young Won Lim 10/4/16

The Complexity of Algorithms (3A) Young Won Lim 4/3/18

Arrays (1A) Young Won Lim 1/27/17

Binary Search Tree (3A) Young Won Lim 6/4/18

Background Functions (1C) Young Won Lim 12/6/17

Applications of Pointers (1A) Young Won Lim 12/26/17

Algorithms Overview (1A) Young Won Lim 3/29/18

Binary Search Tree (3A) Young Won Lim 6/6/18

A Sudoku Solver (1A) Richard Bird Implementation. Young Won Lim 11/15/16

DerivingVia or, How to Turn Hand-Written Instances into an Anti-Pattern

Pointers (1A) Young Won Lim 2/6/18

Pointers (1A) Young Won Lim 1/22/18

Monads. Functional Programming (CS4011) Monads

Transcription:

Comparisons (2C)

Copyright (c) 2016-2018 Young W. Lim. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". Please send corrections (or suggestions) to youngwlim@hotmail.com. This document was produced by using LibreOffice.

Based on http://learnyouahaskell.com/making-our-own-types-and-typeclasses#the-functor-typeclass http://learnyouahaskell.com/functors-applicative-functors-and-monoids Haskell in 5 steps https://wiki.haskell.org/haskell_in_5_steps Comparisons (2C) 3

The Applicative Typeclass a bonus law about the relation between fmap and (<*>): fmap f x = pure f <*> x -- fmap Applying a "pure" function with (<*>) is equivalent to using fmap. This law is a consequence of the other ones, so you need not bother with proving it when writing instances of Applicative. https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 4

(1) >>> [(2*),(3*)] <*> [4,5] [8,10,12,15] >>> [4,5] <**> [(2*),(3*)] [8,12,10,15] [(2*)] <*> [4,5], [(3*)] <*> [4,5] [4] <**> [(2*),(3*)], [5] <**> [(2*),(3*)] Prelude> Just 2 *> Just 3 Just 3 Prelude> Just 3 *> Just 2 Just 2 Prelude> Just 2 *> Nothing Nothing Prelude> Nothing *> Just 2 Nothing https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 5

Prelude> (print "foo" *> pure 2) *> (print "bar" *> pure 3) "foo" "bar" 3 Prelude> (print "bar" *> pure 3) *> (print "foo" *> pure 2) "bar" "foo" 2 Prelude> (print "foo" *> pure 2) <* (print "bar" *> pure 3) "foo" "bar" 2 https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 6

By the way, if you hear about commutative monads in Haskell, the concept involved is the same, only specialised to Monad. Commutativity (or the lack thereof) affects other functions which are derived from (<*>) as well. (*>) is a clear example: (*>) :: Applicative f => f a -> f b -> f b (*>) combines effects while preserving only the values of its second argument. For monads, it is equivalent to (>>). Here is a demonstration of it using Maybe, which is commutative: https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 7

(<**>) :: Applicative f => f a -> f (a -> b) -> f b from Control.Applicative is not flip (<*>). That means it provides a way of inverting the sequencing: https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 8

The convention in Haskell is to always implement (<*>) and other applicative operators using left-to-right sequencing. Even though this convention helps reducing confusion, it also means appearances sometimes are misleading. For instance, the (<*) function is not flip (*>), as it sequences effects from left to right just like (*>): https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 9

Functor, Applicative, Monad. Three closely related functor type classes; *2 3 6 the characteristic methods of the three classes fmap :: Functor f => (a -> b) -> f a -> f b (<*>) :: Applicative f => f (a -> b) -> f a -> f b (>>=) :: Monad m => m a -> (a -> m b) -> m b fmap Just 3 Just 6 Just *2 <*> Just 3 Just 6 https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 10

replace fmap by its infix synonym, (<$>); replace (>>=) by its flipped version, (=<<); fmap :: Functor f => (a -> b) -> f a -> f b (<*>) :: Applicative f => f (a -> b) -> f a -> f b (>>=) :: Monad m => m a -> (a -> m b) -> m b (<$>) :: Functor t => (a -> b) -> (t a -> t b) (<*>) :: Applicative t => t (a -> b) -> (t a -> t b) (=<<) :: Monad t => (a -> t b) -> (t a -> t b) https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 11

fmap, (<*>) and (=<<) are all mapping functions over Functors. The differences between them are in what is being mapped over in each case: (<$>) :: Functor t => (a -> b) -> (t a -> t b) (<*>) :: Applicative t => t (a -> b) -> (t a -> t b) (=<<) :: Monad t => (a -> t b) -> (t a -> t b) fmap maps arbitrary functions over functors. (<*>) maps t (a -> b) morphisms over (applicative) functors. (=<<) maps a -> t b functions over (monadic) functors. https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 12

The day-to-day differences in uses of Functor, Applicative and Monad follow from what the types of those three mapping functions allow you to do. As you move from fmap to (<*>) and then to (>>=), you gain in power, versatility and control, at the cost of guarantees about the results. We will now slide along this scale. While doing so, we will use the contrasting terms values and context to refer to plain values within a functor and to whatever surrounds them, respectively. https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 13

The type of fmap ensures that it is impossible to use it to change the context, no matter which function it is given. In (a -> b) -> t a -> t b, the (a -> b) function has nothing to do with the t context of the t a functorial value, and so applying it cannot affect the context. For that reason, if you do fmap f xs on some list xs the number of elements of the list will never change. https://en.wikibooks.org/wiki/haskell/applicative_functors Comparisons (2C) 14

Functor map <$> (<$>) :: Functor f => (a -> b) -> f a -> f b (<$) :: Functor f => a -> f b -> f a ($>) :: Functor f => f a -> b -> f b The <$> operator is just a synonym for the fmap function from the Functor typeclass. This function generalizes the map function for lists to many other data types, such as Maybe, IO, and Map. https://haskell-lang.org/tutorial/operators Comparisons (2C) 15

Functor map <$> (<$>) :: Functor f => (a -> b) -> f a -> f b (<$) :: Functor f => a -> f b -> f a ($>) :: Functor f => f a -> b -> f b The <$> operator is just a synonym for the fmap function from the Functor typeclass. This function generalizes the map function for lists to many other data types, such as Maybe, IO, and Map. https://haskell-lang.org/tutorial/operators Comparisons (2C) 16

#!/usr/bin/env stack -- stack --resolver ghc-7.10.3 runghc import Data.Monoid ((<>)) main :: IO () main = do putstrln "Enter your year of birth" year <- read <$> getline let age :: Int age = 2020 - year putstrln $ "Age in 2020: " <> show age https://haskell-lang.org/tutorial/operators Comparisons (2C) 17

In addition, there are two additional operators provided which replace a value inside a Functor instead of applying a function. This can be both more convenient in some cases, as well as for some Functors be more efficient. In terms of definition: value <$ functor = const value <$> functor functor $> value = const value <$> functor x <$ y = y $> x x $> y = y <$ x https://haskell-lang.org/tutorial/operators Comparisons (2C) 18

Applicative function application <*> (<*>) :: Applicative f => f (a -> b) -> f a -> f b (*>) :: Applicative f => f a -> f b -> f b (<*) :: Applicative f => f a -> f b -> f a Commonly seen with <$>, <*> is an operator that applies a wrapped function to a wrapped value. It is part of the Applicative typeclass, and is very often seen in code like the following: foo <$> bar <*> baz https://haskell-lang.org/tutorial/operators Comparisons (2C) 19

For cases when you're dealing with a Monad, this is equivalent to: do x <- bar y <- baz return (foo x y) Other common examples including parsers and serialization libraries. Here's an example you might see using the aeson package: data Person = Person { name :: Text, age :: Int } deriving Show -- We expect a JSON object, so we fail at any non-object value. instance FromJSON Person where parsejson (Object v) = Person <$> v.: "name" <*> v.: "age" parsejson _ = empty https://haskell-lang.org/tutorial/operators Comparisons (2C) 20

To go along with this, we have two helper operators that are less frequently used: *> ignores the value from the first argument. It can be defined as: a1 *> a2 = (id <$ a1) <*> a2 Or in do-notation: a1 *> a2 = do _ <- a1 a2 For Monads, this is completely equivalent to >>. https://haskell-lang.org/tutorial/operators Comparisons (2C) 21

<* is the same thing in reverse: perform the first action then the second, but only take the value from the first action. Again, definitions in terms of <*> and do-notation: (<*) = lifta2 const a1 <* a2 = do res <- a1 _ <- a2 return res https://haskell-lang.org/tutorial/operators Comparisons (2C) 22

References [1] ftp://ftp.geoinfo.tuwien.ac.at/navratil/haskelltutorial.pdf [2] https://www.umiacs.umd.edu/~hal/docs/daume02yaht.pdf