Learn&Func*onal&Programming&with& PureScript (Or$I'll$buy$you$a$coffee!) John%A.%De%Goes%—%@jdegoes

Agenda •

Func&ons



Types,.Kinds,.&.More.Func&ons



FP.Toolbox



OMG.COFFEE.BREAK!!!



Type.Classes,.Effects



Scary.Sounding.Things



Let's.Build.a.Game!

Func%onal)Programming It's%all%about%func.ons.

Func%on'Defini%on data Food = Eggs | Coffee data Happiness = Happy | Neutral | Unhappy john :: Food -> Happiness john Eggs = Unhappy john Coffee = Happy

Func%on'Applica%on > john Eggs Unhappy > john Coffee Happy

The$Real$Deal 1. Totality.#Every#element#in#domain#must#be#mapped#to#some# element#in#codomain. 2. Determinism.#Applying#a#func:on#with#the#same#value#(in# domain)#results#in#same#value#(in#codomain).

Exercises superpower :: CharacterClass -> Superpower weakness :: Superpower -> Kryptonite

1. Create(a(set(called(CharacterClass,(which(represents(the(different(types(of( characters. 2. Create(a(set(called(Superpower,(which(represents(different(superpowers. 3. Create(a(set(called(Kryptonite,(which(represents(different(weaknesses(for( characters. 4. Create(the(above(func>ons(superpower(and(weakness,(and(apply(them(at( various(elements(in(their(domain.

Types Sets%of%values.

Literal(Types •

String":"The"set"that"contains"all"strings;""foo""is"an"element" of"this"set. 0



Number":"The"set"that"contains"all"numbers; "5.5"is"an"element" of"this"set.



Boolean":"The"set"that"contains"the"values"true"and"false.

0

"Not"really,"$%#@&!!

1

Product(Types data Loc = Loc Number Number

1

"They"get"their"name"from"an"easy"way"you"can"use"to"compute"the"size"of"these"sets"(hint:"product"="mul;plica;on).

Product(Types data Loc = Loc Number Number -| -| -| -- The name of -the type.

Product(Types data Loc = Loc Number Number -| -| -| -- The name of a function -- that will create values -- of the type. AKA the -constructor!

Product(Types data Loc = Loc Number Number -\ / -\ / -\ / -\/ -Constructor parameters (types).

Product(Types data Loc = Loc Number Number whereAmI = Loc 1 2

Product(Types What's'the'opposite'of'construc0on?4 locX :: Loc -> Number locX (Loc x _) = x locY :: Loc -> Number locY (Loc _ y) = y locX (Loc 1 2) -- 1 locY (Loc 1 2) -- 2 4

"Deconstruc*on,"of"course!"AKA"pa%ern(matching.

Product(Types Another(way(to(deconstruct. locX :: Loc -> Number locX l = case l of (Loc x _) -> x

Exercises 1. Create(a(CharacterStats(product(type(to(model(some( character(sta3s3cs(in(an(role6playing(game((e.g.(health,(strength,( etc.). 2. Create(some(values(of(that(type(to(understand(how(to(use(data( constructors. 3. Use(paAern(matching(to(extract(individual(components(out(of( the(data(type.

Coproduct)Types (AKA$'Sum'$Types)2 data NPC = Ogre String Loc Number | Wolf String Loc Number

2

"They"get"their"name"from"an"easy"way"you"can"use"to"compute"the"size"of"these"sets"(hint:"sum"="addi:on).

Coproduct)Types -- The name of -- the type -| -| data NPC = Ogre String Loc Number | Wolf String Loc Number

Coproduct)Types data NPC = Ogre String Loc Number | Wolf String Loc Number -| -| -- Data constructor.

Coproduct)Types data NPC = Ogre String Loc Number | Wolf String Loc Number -| | | -\ | / -\ | / -Constructor parameters (types).

Coproduct)Types Destruc(on+/+pa/ern+matching. nameOf :: NPC -> String nameOf (Ogre name _ _) = name nameOf (Wolf name _ _) = name

Coproduct)Types Deconstruc*on+/+pa/ern+matching. data NPC = Ogre String Loc Number | Wolf String Loc Number nameOf :: NPC -> String nameOf npc = case npc of (Ogre name _ _) -> name (Wolf name _ _) -> name

Exercises 1. Create(a(Monster(sum(type(to(represent(different(types(of( monsters(in(a(game.(Make(sure(they(share(at(least(one(common( piece(of(informa:on((e.g.(health(or(name). 2. Create(a(few(monsters(of(varying(types. 3. Create(a(func:on(to(extract(out(a(piece(of(informa:on(common( to(all(constructors.

Record'Types

5

data NPC = Ogre {name :: String, loc :: Loc, health :: Number} | Wolf {name :: String, loc :: Loc, health :: Number}

5

"Record"types"are"represented"using"na2ve"Javascript"objects.

Record'Types data NPC = Ogre {name :: String, loc :: Loc, health :: Number} | Wolf {name :: String, loc :: Loc, health :: Number} -| | -\----------------------|---------------------/ -| -Record type.

Record'Types data NPC = Ogre {name :: String, loc :: Loc, health :: Number} | Wolf {name :: String, loc :: Loc, health :: Number} -| | -\--------------------|---------------------/ -| -A 'row' of types.

Record'Types data NPC = Ogre {name :: String, loc :: Loc, health :: Number} | Wolf {name :: String, loc :: Loc, health :: Number} -| -A label.

Record'Types data NPC = Ogre {name :: String, loc :: Loc, health :: Number} | Wolf {name :: String, loc :: Loc, health :: Number} -| -The type of the label.

Record'Types Construc)on*/*deconstruc)on. makeWolf :: String -> Loc -> Number -> NPC makeWolf name loc health = Wolf {name: name, loc: loc, health: health} nameOf :: NPC -> String nameOf (Ogre { name : n }) = n nameOf (Wolf { name : n }) = n

Record'Types The$dot$operator. nameOf :: NPC -> String nameOf (Ogre record) = record.name nameOf (Wolf record) = record.name

Record'Types 'Upda&ng')records. changeName :: NPC -> NPC changeName (Ogre r) = Ogre r { name = "Shrek" } changeName (Wolf r) = Wolf r { name = "Big Bad" }

Record'Types Magic&record&syntax&stuff. (_ { name = "Shrek" }) // Function from record to updated record record { name = _ }

// Function from string to updated `record`

_ { name = _ }

// Guess? :-)

Exercises 1. Rework)some)of)your)early)product)types)to)use)records. 2. Create)another)class)called)InventoryItem)whose)constructor) takes)a)record)that)has)fields)relevant)to)items)that)a)player)can) carry)with)her.

Basic&Func*on&Types data Monster = Giant | Alien data FavoriteFood = Humans | Kittens fave :: Monster -> FavoriteFood fave Giant = Humans fave Alien = Kittens

Basic&Func*on&Types Lambdas'AKA'closures'AKA'anonymous'func3ons'AKA'arrow' func3ons'AKA... fave :: Monster -> FavoriteFood fave = \monster -> ... var fave = function(monster) { ... } // ECMAScript 6 var fave = monster => ...

Exercises 1. Create(a(func-on(from(monster(to(total(hit(points((how(much( damage(they(can(take(before(dying). 2. Express(the(same(func-on(as(a(lambda. 3. Apply(the(func-on(at(various(inputs.

Type%Aliases What's'in'a'name? type CharData = {name :: String, loc :: Loc, health :: Number} data NPC = Ogre CharData | Wolf CharData

Newtypes Wrappers'without'the'overhead. newtype Health = Health Number dead = Health 0

Newtypes Deconstruc*on+/+pa/ern+matching. newtype Health = Health Number isAlive :: Health -> Boolean isAlive (Health v) = v > 0 isAlive h = case h of Health v -> v > 0

Exercises 1. Create(a(type(alias(for(a(record(called(MagicalItemRec(which( has(several(fields. 2. Use(the(type(alias(to(define(a(newtype(called(MagicalItem,( whose(constructor(is(called(MagicalItem. 3. Create(some(values(of(type(MagicalItem. 4. Create(a(few(func>ons(to(extract(out(the(fields(of( MagicalItem.

Higher'Order*Func/ons Or,$OMG$sets$can$hold$func3ons!!!

Higher'Order*Func/ons Func%ons(that(accept(func%ons. likesEmptyString :: (String -> Boolean) -> Boolean likesEmptyString f = f ""

Higher'Order*Func/ons Func%ons(that(return(func%ons. matches :: String -> (String -> Boolean) matches v = \text -> text == v matchesEvil = matches "evil" matchesEvil "john" -- false matchesEvil "evil" -- true

Higher'Order*Func/ons "Mul%¶meter"-func%ons.6 damageNpc :: Number -> (NPC -> NPC) damageNpc damage = \npc -> ...

6

"Not"really,"of"course:"func/ons"in"PureScript"are"always"func/ons"from"one"set"to"another"set.

Higher'Order*Func/ons Making'sense'of'"mul01parameter"'func0ons:'values. f a b c d e -- (((((f a) b) c) d) e)

Higher'Order*Func/ons Making'sense'of'"mul01parameter"'func0ons:'types. f :: a -> b -> c -> d -> e -- f :: (a -> (b -> (c -> (d -> e))))

Higher'Order*Func/ons MORE%func*ons%that%return%func*ons. damageNpc :: Number -> (NPC -> NPC) damageNpc = \damage -> \npc -> ...

damageNpc :: Number -> (NPC -> NPC) damageNpc = \damage npc -> ... damageNpc :: Number -> (NPC -> NPC) damageNpc damage = \npc -> ... damageNpc :: Number -> (NPC -> NPC) damageNpc damage npc = ...

Exercises damagerOf :: String -> (NPC -> NPC) type Damager = Number -> NPC -> NPC

1. Create(a(func-on(damagerOf(that(takes(a(name((String),(and( returns(another(func-on(that(damages(an(NPC(but(only(if(its( name(is(equal(to(the(specified(name. 2. Create(a(func-on(boostDamage(which(takes(a(Damager( (defined(above)(and(returns(another(Damager(that(boosts(the( damage(done(by(the(passed(in(damager(by(10%.

Parametric)Polymorphism Para..what?

Polymorphic+Data Type%constructors:%data%with%"holes". data Map4x4 a = Map4x4 a a a a boolMap4x4 = Map4x4 true false false true

a a a a

a a a a

a a a a

true true false false

false true false false

true true true true

Polymorphic+Data Type%level(func-ons. -- invalid :: Map4x4 valid :: Map4x4 Boolean

The$type$constructor$Map4x4$is$a$func1on$whose$ domain$is$the$set$of$all$types,$and$whose$codomain$is$a$ family$of$Map4x4 a$types.

Polymorphic+Func/ons Or,$OMG$sets$can$hold$sets!!!

Polymorphic+Func/ons The$heart$of$func-onal$abstrac-on. upperLeft :: forall a. Map4x4 a -> a upperLeft v _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = v

Polymorphic+Func/ons How$to$read$these$crazy$signatures. upperLeft :: forall a. Map4x4 a -> a -- (a :: Type) -> Map4x4 a -> a

Exercises data TreasureChest a = ??? isEmpty :: ???

1. Create(a(polymorphic(TreasureChest(sum(type(that(can(either( contain(any(type(of(thing,(or(be(empty. 2. Create(a(polymorphic(func9on(that(determines(whether(or(not( any(treasure(chest(is(empty.

Extensible*Rows Like%duck%typing%only%be1er. type Point r = { x :: Number, y :: Number | r }

Extensible*Rows Like%duck%typing%only%be1er. type Point r = { x :: Number, y :: Number | r } -| | -| | -'remainder' syntax that means "the rest of the row" gimmeX :: forall r. Point r -> Number gimmeX p = p.x gimmeX {x: 1, y: 2, z: 3} -- 1 - works! -- gimmeX {x: 1, z: 3}

-- Invalid, no x!

Exercises type NonPlayerCharacterRec = ??? type ItemRec = ??? type PlayerCharacterRec = ??? getName :: ??? getName r = r.name

1. Create(records(for(NonPlayerCharacter,(Item,(and( PlayerCharacter(that(all(share(at(least(one(field((name?). 2. Create(a(func8on(that(extracts(a(name(from(any(record(which(has(at# least(a(name(field(of(type(String.

Kinds Categories*of*sets.

* The$name$for$the$category$of$sets$of$values. (AKA$Type) Includes)things)like: •

CharacterClass"



Superpower



String

* -> * The$name$for$the$category$of$type%level(func-ons. (AKA$Higher+Kinded$Type$/$Type$Constructor)

* -> * data List a = Nil | Cons a (List a)

* -> * Type%constructors%are%just%(math)%func4ons! addOne :: Number -> Number addOne n = n + 1 List :: * -> * data List a = Nil | Cons a (List a)

* -> * -> * Turtles(all(the(way(down. Map :: * -> * -> * data Map k v = ...

(* -> *) -> * More%turtles. Container :: (* -> *) -> * data Container f = {create :: forall a. a -> f a} list :: Container List list = Container {create: \a -> Cons a Nil}

* -> * -> * -> * -> * -> * Reading(type(constructors. foo :: f a b c d e -- (((((f a) b) c) d) e)

! The$name$for$the$category$of$sets$of$effects. foreign import data DOM :: !

# ! The$name$for$the$category$of$rows%of%effects. -- Supply a row of effects and a type, -- and get back another type: foreign import data Eff :: # ! -> * -> * trace :: forall r. String -> Eff (trace :: Trace | r) Unit

# * The$name$for$the$category$of$rows%of%types. -- Supply a row of types, get back another type: foreign import data Object :: # * -> *

7

Foreign(Types foreign import data jQuery :: *

7

"THERE"BE"DRAGONZ"HERE!!!

FP#Toolbox Stuff%you%couldn't%escape%even%if%you%wanted%to.

FP#Toolbox Maybe&it's&there,&maybe&it's¬?8 data Maybe a = Nothing | Just a type Player = { armour :: Maybe Armor }

8

"AKA"null,"the"FP"way.

FP#Toolbox List:&the&ul+mate&FP&data&structure. data List a = Nil | Cons a (List a) -| | -head | -tail oneTwoThree = Cons 1 (Cons 2 (Cons 3 Nil))

FP#Toolbox Either!it's!this!or!it's!that. data Either a b = Left a | Right b type Player = { rightHand :: Either Weapon Shield }

FP#Toolbox Tuple,"the"opposite"of"Either.9 data Tuple a b = Tuple a b -| | -first second I type Player = { wrists :: Tuple (Maybe Bracelet) (Maybe Bracelet) }

9

"AKA"some)mes"it's"just"too"damn"hard"to"name"stuff!

FP#Toolbox Na#ve&Javascript&arrays. [1, 2, 3] :: [Number]

Exercises 1. Use&all&the&data&structures&you've&learned&about&(Maybe,& Either,&Tuple,&and&[])&to&build&a&representa:on&of&character& state&called&CharacterState. 2. Define&a&few&func:ons&to&extract&some&informa:on&out&of&the& data&structure.

Type%Classes Generic'interfaces,'the'FP'way.

Type%Classes Generic'interfaces'in'Java. public interface Appendable { public A append(A a1, A a2); } class AppendableNumber extends Appendable { public Float append(Float a1, Float a2) { return a1 + a2; } } Appendable appendableNumber = new AppendableNumber(); appendableNumber.append(1, 2); // 3!

Type%Classes Generic''interfaces''in'Javascript. function makeAppendable(append) { return { append: append }; } var boolAppendable = makeAppendable( function(v1, v2) { return v1 && v2; } ); boolAppendable.append(true, false); // false!

Type%Classes Generic'interfaces'in'PureScript. class Appendable a where append :: a -> a -> a instance appendableNumber :: Appendable Number where append a1 a2 = a1 + a2 append 1 2 -- 3!

Type%Classes Turbocharged,polymorphism. repeat :: forall a. (Appendable a) => Number -> a -> a repeat 0 a = a repeat n a = append (repeat (n - 1) a) a sort :: forall a. (Ord a) => [a] -> [a] -- etc.

Type%Classes Hierarchies:*like*OO*inheritance,*but*not. class Eq a where equals :: a -> a -> Boolean data Ordering = LT | GT | EQ class (Eq a) <= Ord a where compare :: a -> a -> Ordering

Type%Classes Hierarchies:*like*OO*inheritance,*but*not. class (Eq a) <= Ord a where -| -| -- The superclass. --- Read: "Ord a implies Eq a"

Exercises class Describable a where describe :: a -> String data Weapon = Sword | Spear instance describableWeapon :: ???

1. Create(an(instance(of(Describable(for(Weapon. 2. Create(instances(of(Eq((the(equal(type(class)(for(some(of(the(data( types(you(created.

Effects Or,$how$to$get$in$trouble$fast.

import Debug.Trace main = trace "Hello World!"

import Debug.Trace main = do trace "Hello World!" trace "Bye World!"

Exercises 1. Import)Debug.Trace)and)make)your)very)own)'Hello)World') program.

Scary&Sounding&Things Monadic(zygohistomorphic(prepromorphisms...

WTF?!?!!

Scary&Sounding&Things Let's&play&a&game:&give&your&friend&a&birthday&present&that&she'll& adore.

Scary&Sounding&Things The$rules$of$the$game. Rule%1:"If"something"is"inside"a"box,"you"may"change"it"to"anything" else"and"the"result"will"s9ll"be"inside"the"box. Rule%2:"If"something"is"not"inside"a"box,"you"can"pack"it"into"a"box. Rule%3:"If"something"is"packed"inside"a"box"which"is"packed"inside" another"box,"you"can"replace"that"with"a"single"box"containing"that" thing.

Scary&Sounding&Things Your%inventory. Item%1:"You"have"Ripley,"a"Chihuaha"mu2"who"can"magically"change" a"lump"of"coal"into"a"beau:ful"present"that"your"friend"will"like. Item%2:"You"have"a"box"containing"a"box"containing"a"lump"of"coal. Which%rules%should%you%apply%to%create%a%birthday%present%your% friend%will%adore???

Scary&Sounding&Things The$rules$of$the$game,$redux. Rule%1:"If"something"is"inside"a"box,"you"may"change"it"to"anything"else"and" the"result"will"s9ll"be"inside"the"box." (a -> b) -> f a -> f b Rule%2:"If"something"is"not"inside"a"box,"you"can"pack"it"into"a"box. a -> f a Rule%3:"If"something"is"packed"inside"a"box"which"is"packed"inside"another" box,"you"can"replace"that"with"a"single"box"containing"that"thing. f (f a) -> f a

Scary&Sounding&Things The$rules$of$the$game,$redux$redux. fmap :: (a -> b) -> f a -> f b -- AKA (<$>) pure :: a -> f a

-- AKA return

join :: f (f a) -> f a -- bind AKA (>>=) = \fa f -> join (fmap f fa)

OMG$a$monad,$run$in$terror!!!!!

Nah,%just%kidding Scary&sounding&things&give&you&rewrite&rules& you&can&use&to&manipulate&the&types&into&the& form&you&require.

The$scary$sounding$names$don't& ma)er$at$all

Exercises class Evitacilppa f where erup :: forall a. a -> f a pa :: forall a b. f (a -> b) -> f a -> f b

1. You&are&given&f Number&and&Number,&for&some&Evitacilppa f.& If&you&have&a&func7on: add :: Number -> Number -> Number which&"rewrite&rules"&do&you&need&to&use&so&that&you&can&apply&the& add&func7on&to&the&two&numbers?

Let's&Build&a&Game! Enough'math'already'plz!!!

The$Soul$of$an$RPG Or#the#types,#anyway. type Game s i initial :: describe :: parse :: update ::

= { s, s -> String, String -> Either String i, s -> i -> Either String s }

runGame :: forall s i. Game s i -> Eff (game :: GAME) Unit runGame g = ...

On#Your#Marks,#Get#Set,#Go!

THANK&YOU! John%A.%De%Goes%—%@jdegoes (Do$I$owe$you$a$coffee?)

(Or$I'll$buy$you$a$coffee!) John%A.%De%Goes ... - GitHub

characters. 4. Create(the(above(func>ons(superpower(and(weakness,(and(apply(them(at( various(elements(in(their(domain.

2MB Sizes 3 Downloads 247 Views

Recommend Documents

GitHub
domain = meq.domain(10,20,0,10); cells = meq.cells(domain,num_freq=200, num_time=100); ...... This is now contaminator-free. – Observe the ghosts. Optional ...

GitHub
data can only be “corrected” for a single point on the sky. ... sufficient to predict it at the phase center (shifting ... errors (well this is actually good news, isn't it?)

Torsten - GitHub
Metrum Research Group has developed a prototype Pharmacokinetic/Pharmacodynamic (PKPD) model library for use in Stan 2.12. ... Torsten uses a development version of Stan, that follows the 2.12 release, in order to implement the matrix exponential fun

Untitled - GitHub
The next section reviews some approaches adopted for this problem, in astronomy and in computer vision gener- ... cussed below), we would question the sensitivity of a. Delaunay triangulation alone for capturing the .... computation to be improved fr

ECf000172411 - GitHub
Robert. Spec Sr Trading Supt. ENA West Power Fundamental Analysis. Timothy A Heizenrader. 1400 Smith St, Houston, Tx. Yes. Yes. Arnold. John. VP Trading.

Untitled - GitHub
Iwip a man in the middle implementation. TOR. Andrea Marcelli prof. Fulvio Risso. 1859. Page 3. from packets. PEX. CethernetDipo topo data. Private. Execution. Environment to the awareness of a connection. FROG develpment. Cethernet DipD tcpD data. P

BOOM - GitHub
Dec 4, 2016 - 3.2.3 Managing the Global History Register . ..... Put another way, instructions don't need to spend N cycles moving their way through the fetch ...

Supervisor - GitHub
When given an integer, the supervisor terminates the child process using. Process.exit(child, :shutdown) and waits for an exist signal within the time.

robtarr - GitHub
http://globalmoxie.com/blog/making-of-people-mobile.shtml. Saturday, October ... http://24ways.org/2011/conditional-loading-for-responsive-designs. Saturday ...

MY9221 - GitHub
The MY9221, 12-channels (R/G/B x 4) c o n s t a n t current APDM (Adaptive Pulse Density. Modulation) LED driver, operates over a 3V ~ 5.5V input voltage ...

fpYlll - GitHub
Jul 6, 2017 - fpylll is a Python (2 and 3) library for performing lattice reduction on ... expressiveness and ease-of-use beat raw performance.1. 1Okay, to ... py.test for testing Python. .... GSO complete API for plain Gram-Schmidt objects, all.

article - GitHub
2 Universidad Nacional de Tres de Febrero, Caseros, Argentina. ..... www-nlpir.nist.gov/projects/duc/guidelines/2002.html. 6. .... http://singhal.info/ieee2001.pdf.

PyBioMed - GitHub
calculate ten types of molecular descriptors to represent small molecules, including constitutional descriptors ... charge descriptors, molecular properties, kappa shape indices, MOE-type descriptors, and molecular ... The molecular weight (MW) is th

MOC3063 - GitHub
IF lies between max IFT (15mA for MOC3061M, 10mA for MOC3062M ..... Dual Cool™ ... Fairchild's Anti-Counterfeiting Policy is also stated on ourexternal website, ... Datasheet contains the design specifications for product development.

MLX90615 - GitHub
Nov 8, 2013 - of 0.02°C or via a 10-bit PWM (Pulse Width Modulated) signal from the device. ...... The chip supports a 2 wires serial protocol, build with pins SDA and SCL. ...... measure the temperature profile of the top of the can and keep the pe

Covarep - GitHub
Apr 23, 2014 - Gilles Degottex1, John Kane2, Thomas Drugman3, Tuomo Raitio4, Stefan .... Compile the Covarep.pdf document if Covarep.tex changed.

SeparableFilter11 - GitHub
1. SeparableFilter11. AMD Developer Relations. Overview ... Load the center sample(s) int2 i2KernelCenter ... Macro defines what happens at the kernel center.

Programming - GitHub
Jan 16, 2018 - The second you can only catch by thorough testing (see the HW). 5. Don't use magic numbers. 6. Use meaningful names. Don't do this: data("ChickWeight") out = lm(weight~Time+Chick+Diet, data=ChickWeight). 7. Comment things that aren't c

SoCsploitation - GitHub
Page 2 ... ( everything – {laptops, servers, etc.} ) • Cheap and low power! WTF is a SoC ... %20Advice_for_Shellcode_on_Embedded_Syst ems.pdf. Tell me more! ... didn't destroy one to have pretty pictures… Teridian ..... [email protected].

Datasheet - GitHub
Dec 18, 2014 - Compliant with Android K and L ..... 9.49 SENSORHUB10_REG (37h) . .... DocID026899 Rev 7. 10. Embedded functions register mapping .

Action - GitHub
Task Scheduling for Mobile Robots Using Interval Algebra. Mudrová and Hawes. .... W1. W2. W3. 0.9 action goto W2 from W1. 0.1. Why use an MDP? cost = 54 ...