108
Haskell a lazy, purely func1onal language COS 326 David Walker Princeton University slides copyright 2013-2015 David Walker and Andrew W. Appel permission granted to reuse these slides for non-commercial educa1onal purposes

Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

  • Upload
    others

  • View
    13

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Haskellalazy,purelyfunc1onallanguage

COS326DavidWalker

PrincetonUniversityslidescopyright2013-2015DavidWalkerandAndrewW.Appel

permissiongrantedtoreusetheseslidesfornon-commercialeduca1onalpurposes

Page 2: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HaskellAnothercool,typed,func1onalprogramminglanguage•  LikeOCamlinthat:

–  itisafunc1onallanguagewithparametricpolymorphism•  UnlikeOCamlinthatitis:

–  pure:func1onswithtypea->bhavenoeffect!–  lazy:fedoesnotevaluateerightaway;passesetof–  hasaweakmodulesystem;usestypeclasses–  hasaverysophis1catedtypesystemwithhigherkinds–  hasseveralcoolextensionsforconcurrentandparallelprogrammingincludingtransac1onalmemory

Page 3: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Glasgowinthe1990s

PhilWadler(nowatU.Edinburgh)

SimonPeytonJones(nowatMicrosoZResearch,

Cambridge,England)

ghc standsfor“GlasgowHaskellCompiler”

Edinburghinthe1970sRobinMilner,LucaCardelli,LuisDamas,MadsToZe...createdMLlanguage

Whyarewege`ngallourfunc1onalprogramminglanguagesfromScotland?

CreatorsofHaskelllanguage

Page 4: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HASKELLBASICS

Page 5: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HaskellDefini1ons•  MostlylikeOCaml,withafewsmallsyntac1cdifferences

–  parametersareimmutablebydefault–  letdeclara1onsintroducenewfunc1onsandvalue

–  equivalently,wemightusea"where"defini1on:

fooz=lettriplex=x*3intriplezfooz=triplezwheretriplex=x*3

Page 6: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HaskellIndenta1on•  Haskell,likePython,butunlikeJava,OCamlormathwrihenin

anotebook,hasseman1callymeaningfulindenta1on•  Wrong:

copieskn=ifn==0then[]elsek:copiesk(n-1)

zapz=letx=zy=z+zinx+y

mustindentfunc1onbody

zapz=letx=zy=z+zinx+yindenty=...

indentz+z

Page 7: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HaskellIndenta1on•  Haskell,likePython,butunlikeJava,OCamlormathwrihenin

anotebook,hasseman1callymeaningfulindenta1on•  Right:

zapz=letx=zy=z+zinx+y

copieskn=ifn==0then[]elsek:copiesk(n-1)

zapz=letx=zy=z+zinx+y

beginningofxdefinesindenta1onlevel

Page 8: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HaskellTypes•  Wehavetheop1onofdeclaringthetypeofadefini1onprior

tothedefini1onitself

zap::Int->Intzapz=letx=zy=z+zinx+y

justtobeannoying,Haskelluses"::"for"hastype"anduses":"for"cons"–theoppositeofML

Page 9: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Tuples•  HaskellusestupleslikeML

–  constructedbyenclosingasequenceofvaluesinparens:

–  deconstructed(used)viapahernmatching:

(‘b’,4)::(Char,Integer)

easytoo::(Integer,Integer,Integer)->Integereasytoo(x,y,z)=x+y*z

Page 10: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Lists•  ListsareverysimilartoMLlistsbutthetypeiswrihen[t]

insteadof"tlist"

•  []istheemptylist(callednil)•  1:2:[]isalistwith2elements•  Stringisasynonymfor[Char]•  Wecanbuildlistsoflists:

[1,2,3]::[Integer][‘a’,‘b’,‘c’]::[Char]

[[1,2],[3],[8,9,10]]::[[Integer]]

Page 11: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Func1onsoverlists

--SumtheelementsofalistlistSum::[Integer]->IntegerlistSum[]=0listSum(x:xs)=x+listSumxs

commontowritefunc1onsusingmul1pleclauses,whereeachclausematchesonadifferentcase

Page 12: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Func1onsdeconstruc1nglists

--SumtheelementsofalistlistSum::[Integer]->IntegerlistSum[]=0listSum(x:xs)=x+listSumxs

length::[a]->Intlength[]=0length(x:xs)=1+lengthxs

lowercaseleher=anytypeatall(atypevariable)

uppercaseleher=aconcretetype

Page 13: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Func1onsdeconstruc1nglists

--SumtheelementsofalistlistSum::[Integer]->IntegerlistSum[]=0listSum(x:xs)=x+listSumxs

length::[a]->Intlength[]=0length(x:xs)=1+lengthxs

cat::[a]->[a]->[a]cat[]xs2=xs2cat(x:xs)xs2=x:(catxsxs2)

Page 14: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Func1onsdeconstruc1nglists

--SumtheelementsofalistlistSum::[Integer]->IntegerlistSum[]=0listSum(x:xs)=x+listSumxs

length::[a]->Intlength[]=0length(x:xs)=1+lengthxs

(++)::[a]->[a]->[a](++)[]xs2=xs2(++)(x:xs)xs2=x:(xs++xs2)

cat::[a]->[a]->[a]cat[]xs2=xs2cat(x:xs)xs2=x:(catxsxs2)

Page 15: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

PURITY&SUBSTITUTIONOFEQUALSFOREQUALS

Page 16: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Subs1tu1onofEqualsforEquals•  AkeylawaboutHaskellprograms:

•  Forexample:

letx=<exp>in...x...x... ...<exp>...<exp>...

letx=4`div`2inx+5+x

(4`div`2)+5+(4`div`2)

9

=

==

*Note:notnecessarilythesamerun1me;(4`div`2)willbeevaluatedtwiceinsteadofonce.

Page 17: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Subs1tu1onofEqualsforEquals•  We'dalsoliketousefunc1onalabstrac1onwithoutpenalty

•  Andinsteadoftellingclientsaboutallimplementa1ondetails,

simplyexposekeylaws:

•  Nowwecanreasonlocallywithintheclient:

halve::Int->Inthalven=n`div`2

(halve4)+y+(halve4)letx=halve4inx+y+x ==

Lemma1:foralln,ifevennthen(halven+halven)=n

(halve4)+(halve4)+y

4+y=

(subs1tu1on)

(arithme1c)

(Lemma1)

Page 18: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Computa1onalEffects•  Whathappenswhenweaddmutabledatastructures?•  ConsiderthisOCamlprogram:

•  Welosealotofreasoningpower!

letx=ref0letfoo(y:int):int=x:=!x+1;arg+!x;

lety=foo3iny+y ≠ foo3+foo3

foo:int->int

Page 19: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Computa1onalEffects•  Whathappenswhenweaddmutabledatastructures?•  ConsiderthisOCamlprogram:

•  Welosealotofreasoningpower!

letx=ref0letfoo(y:int):int=x:=!x+1;arg+!x;

lety=foo3iny+y ≠ foo3+foo3

foo:int->int

8 9

Page 20: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Computa1onalEffects•  Whathappenswhenweaddmutabledatastructures?•  ConsiderthisOCamlprogram:

•  Welosealotofreasoningpower!

letfoo(y:int):int=print_inty;arg+!x;

lety=foo3iny+y ≠ foo3+foo3

foo:int->int

6prin1ng"3" 6prin1ng"33"

Page 21: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Computa1onalEffects•  Afunc1onhasaneffectifitsbehaviorcannotbespecified

exclusivelyasarela1onbetweenitsinputanditsoutput–  I/Oisaneffect–  Animpera1veupdateofadatastructureisaneffect

•  Whenfunc1onscannolongerbedescribedexclusivelyintermsoftherela1onshipbetweenargumentsandresults–  many,manyfewerequa1onallawshold–  Ingeneral,inOCaml,

–  Ingeneral,inHaskell,

letx=<exp>in...x...x... ...<exp>...<exp>...≠

letx=<exp>in...x...x... ...<exp>...<exp>...=

Page 22: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Computa1onalEffects•  Afunc1onhasaneffectifitsbehaviorcannotbespecified

exclusivelyasarela1onbetweenitsinputanditsoutput–  I/Oisaneffect–  Animpera1veupdateofadatastructureisaneffect

•  Whenfunc1onscannolongerbedescribedexclusivelyintermsoftherela1onshipbetweenargumentsandresults–  many,manyfewerequa1onallawshold–  Ingeneral,inOCaml,

–  Ingeneral,inHaskell,

letx=<exp>in...x...x... ...<exp>...<exp>...≠

letx=<exp>in...x...x... ...<exp>...<exp>...=

Thisiskindofmagical!Haskellhassubs1tu1onof

equalsforequalsANDALSOHASEFFECTS.

Buthow?

Page 23: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

DIGRESSION:MONADSANDLISTCOMPREHENSIONS

Page 24: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListcomprehensionsExample:Findall(a,b,c)suchthat1≤a≤b≤c≤25anda2+b2=c2pabc=a*a+b*b=c*ctriples=doa<-[1..25]b<-[a..25]c<-[b..25]guard(pabc)return(a,b,c)

Source:GregBacon,hhp://gbacon.blogspot.com/2009/07/programmable-semicolon-explained.html

Page 25: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListcomprehensionsExample:Findall(a,b,c)suchthat1≤a≤b≤c≤25anda2+b2=c2pabc=a*a+b*b=c*ctriples=doa<-[1..25]b<-[a..25]c<-[b..25]guard(pabc)return(a,b,c)

Source:GregBacon,hhp://gbacon.blogspot.com/2009/07/programmable-semicolon-explained.html

Itlookslikesomesortof“iterator”feature;butHaskelldoesn’thavebuilt-in“iterators.”

It'sgotsomethingmoregeneral!Iteratorsariseasanaturalconsequenceof:

purefunc1onalprogramming+lazyevalua1on

+lists+anicenota1onformonadiccomputa/ons

Now,let’s“unpack”thistoseehowthatworks.

Page 26: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListcomprehensionsExample:Findall(a,b,c)suchthat1≤a≤b≤c≤25anda2+b2=c2triples=do{a<-[1..25];b<-[a..25];c<-[b..25];guard(pabc);return(a,b,c)}

Source:GregBacon,hhp://gbacon.blogspot.com/2009/07/programmable-semicolon-explained.html

Analternatesyntaxusingsemi-colons.Thesemi-colonopera1onactuallydoesalotofwork.Itdoesmorethanjust"moveontothenextstatement".It"composes"thefunc1onsdefinedbyeachstatement.

Page 27: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListcomprehensionsExample:Findall(a,b,c)suchthat1≤a≤b≤c≤25anda2+b2=c2triples=do{a<-[1..25];b<-[a..25];c<-[b..25];guard(pabc);return(a,b,c)}

Thisisjustthe“range”operatorforlists;[1..5]isjust[1,2,3,4,5].Easytoconstructthiswith“letrec”inML,orasarecursivefunc1oninHaskell.Nomagichere.

Page 28: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Listcomprehensions“a<-e;…”isjustanota1onalabbrevia1onforthemonadicbindoperatorthatyou’veseenbefore.Haskellmakesiteasytointroducenota1onalabbrevia1onstriples=do{a<-[1..25];b<-[a..25];c<-[b..25];guard(pabc);return(a,b,c)}

triples=[1..25]>>=\a->[a..25]>>=\b->[b..25]>>=\c->guard(pabc)>>return(a,b,c)

That’sλfromlambda-calculus;inMLyou’dwrite

“fun”

Page 29: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Listcomprehensions“a<-e;…”isjustanota1onalabbrevia1onforthemonadicbindoperatorthatyou’veseenbefore.Haskellmakesiteasytointroducenota1onalabbrevia1onstriples=do{a<-[1..25];b<-[a..25];c<-[b..25];guard(pabc);return(a,b,c)}

triples=[1..25]>>=\a->[a..25]>>=\b->[b..25]>>=\c->guard(pabc)>>return(a,b,c)

That’sλfromlambda-calculus;inMLyou’dwrite

“fun”

do{a<-e1;e2} e1>>=(\a->e2) e1>>=(funa->e2)== ==

Page 30: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListMonadYou’veseenmonadsbefore,butletmeremindyou:

(*inOcamlnota1on,notHaskell!*)moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

pronounced“bind”

Onewaytothinkofamonad'aM:Itisaspecialsortof"container"for'a.returnx :putsxintothecontainerc>>=f :extractsitemsfromc;thenpushesthemthroughf,whichgeneratesnewcontainerBind(c>>f)allowsyoutocomputewiththeitemsinsidethecontainer

Page 31: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListMonadYou’veseenmonadsbefore,butletmeremindyou:

(*inOcamlnota1on,notHaskell!*)moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

pronounced“bind”

Onewaytothinkofamonad'aM:Itisaspecialsortof"container"for'a.returnx :putsxintothecontainerc>>=f :extractsitemsfromc;thenpushesthemthroughf,whichgeneratesnewcontainerBind(c>>f)allowsyoutocomputewiththeitemsinsidethecontainer

Whenwediderrorprocessing,thecontainerwasanop1ontype:'aop1on.Atmostonethingwasinthecontainerata1me.

Page 32: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListMonadHere,themonadwewantistheListmonadwithconcatMap

Onemorething:>>isjusta“bind”thatthrowsawayitsargument.let(>>)(m:‘aM)(f:‘bM):‘bM=m>>=fun_->f

(*inOcamlnota1on,notHaskell!*)moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

Page 33: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListMonadHere,themonadwewantistheListmonadwithconcatMap

(*inOcamlnota1on,notHaskell!*)moduleListMonad:MONADtype‘aM=‘alistletreturn(x:‘a)=[x]let(>>=)(as:‘alist)(f:‘a->‘blist):‘blist=reduceappendnil(mapfas)end

(*inOcamlnota1on,notHaskell!*)moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

Page 34: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListMonadHere,themonadwewantistheListmonadwithconcatMap

(*inOcamlnota1on,notHaskell!*)moduleListMonad:MONADtype‘aM=‘alistletreturn(x:‘a)=[x]let(>>=)(as:‘alist)(f:‘a->‘blist):‘blist=reduceappendnil(mapfas)end

(*inOcamlnota1on,notHaskell!*)moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

letdoublea=[a;a]

[1;2;3]>>=double==reduceappendnil[[1;1];[2;2];[3;3]]==[1;1;2;2;3;3]

Page 35: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Exampleletfa=return(a,a)inreduceappendnil(mapf[1,2,3])

=

returnx=[x](>>=)xsf=reduceappendnil(mapfxs)

[1,2,3]>>=\a->return(a,a)

Page 36: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Exampleletfa=return(a,a)inreduceappendnil(mapf[1,2,3])

=

returnx=[x](>>=)xsf=reduceappendnil(mapfxs)

=letfa=return(a,a)inreduceappendnil[f1,f2,f3]

[1,2,3]>>=\a->return(a,a)

Page 37: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Exampleletfa=return(a,a)inreduceappendnil(mapf[1,2,3])

=

returnx=[x](>>=)xsf=reduceappendnil(mapfxs)

=letfa=return(a,a)inreduceappendnil[f1,f2,f3]

= reduceappendnil[return(1,1),return(2,2),return(3,3)]

[1,2,3]>>=\a->return(a,a)

Page 38: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Exampleletfa=return(a,a)inreduceappendnil(mapf[1,2,3])

=

returnx=[x](>>=)xsf=reduceappendnil(mapfxs)

=letfa=return(a,a)inreduceappendnil[f1,f2,f3]

= reduceappendnil[return(1,1),return(2,2),return(3,3)]

[1,2,3]>>=\a->return(a,a)

=reduceappendnil[[(1,1)],[(2,2)],[(3,3)]]

Page 39: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Exampleletfa=return(a,a)inreduceappendnil(mapf[1,2,3])

=

returnx=[x](>>=)xsf=reduceappendnil(mapfxs)

=letfa=return(a,a)inreduceappendnil[f1,f2,f3]

= reduceappendnil[return(1,1),return(2,2),return(3,3)]

[1,2,3]>>=\a->return(a,a)

=reduceappendnil[[(1,1)],[(2,2)],[(3,3)]]

[(1,1),(2,2),(3,3)]=

Page 40: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Example

letfa=[a..4]>>=\b->return(a,b)inreduceappnil(mapf[1,2,3])

=

return(x:‘a)=[x](>>=)(al:[a])(f:a->[b]):[b]=reduceappnil(mapfal)

=letfa=[a..4]>>=\b->return(a,b)inreduceappnil[f1,f2,f3]

= reduceappnil[[1,2,3,4]>>=\b->return(1,b),[2,3,4]>>=\b->return(2,b),[3,4]>>=\b->return(3,b)]

foo=[1..3]>>=\a->[a..4]>>=\b->return(a,b)

Page 41: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Example

letfa=[a..4]>>=\b->return(a,b)inreduceappnil(mapf[1,2,3])

=

return(x:‘a)=[x](>>=)(al:[a])(f:a->[b]):[b]=reduceappnil(mapfal)

=letfa=[a..4]>>=\b->return(a,b)inreduceappnil[f1,f2,f3]

= reduceappnil[[1,2,3,4]>>=\b->return(1,b),[2,3,4]>>=\b->return(2,b),[3,4]>>=\b->return(3,b)]

foo=[1..3]>>=\a->[a..4]>>=\b->return(a,b)

Page 42: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Example

foo=[1..3]>>=\a->[a..4]>>=\b->return(a,b)

=

return (x: ‘a) = [x] (>>=) (al: [a]) (f: a -> [b]) : [b] = reduce app nil (map f al)

=

reduceappnil[[1,2,3,4]>>=\b->return(1,b),[2,3,4]>>=\b->return(2,b),[3,4]>>=\b->return(3,b)]

reduceappnil[reduceappnil[return(1,1),return(1,2),return(1,3),return(1,4)],reduceappnil[return(2,2),return(2,3),return(2,4)],reduceappnil[return(3,3),return(3,4)]]

=reduceappnil[reduceappnil[[(1,1)],[(1,2)],[(1,3)],[(1,4)]],reduceappnil[[(2,2)],[(2,3)],[(2,4)]],reduceappnil[[(3,3)],[(3,4)]]]

Page 43: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Example

[1..3]>>=\a->[a..4]>>=\b->return(a,b)

=

return (x: ‘a) = [x] (>>=) (al: [a]) (f: a -> [b]) : [b] = reduce app nil (map f al)

=

=

reduceappnil[reduceappnil[[(1,1)],[(1,2)],[(1,3)],[(1,4)]],reduceappnil[[(2,2)],[(2,3)],[(2,4)]],reduceappnil[[(3,3)],[(3,4)]]]

reduceappnil[[(1,1),(1,2),(1,3),(1,4)],[(2,2),(2,3),(2,4)]],[(3,3),(3,4)]]]

[(1,1),(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,3),(3,4)]

Page 44: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Isitreallyaniterator?

doa<-[1..3]b<-[a..4]return(a,b)

= [(1,1),(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,3),(3,4)]

Itdoesn’tseemlike“inthespiritofaniterator”toreturnthewholelist;itshouldreturnthepairs(1,1);(1,2);…oneata'me,ondemand.

That’swhatwemeanbyaniterator.

Aha!EveryexpressioninHaskellislazy.Everythingison-demand.Thisreallyisaniterator!

Page 45: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Returningtothe“Pythagoreantriples”…

[1..25]>>=\a->[a..25]>>=\b->[b..25]>>=\c->guard(pabc)>>return(a,b,c)

doa<-[1..25]b<-[a..25]c<-[b..25]guard(pabc)return(a,b,c)

[1..25]>>=\a->[a..25]>>=\b->[b..25]>>=\c->guard(pabc)>>=\_->return(a,b,c)

guard::(MonadPlusm)=>Bool->m()guardTrue=return()guardFalse=mzero

The“zero”fortheListmonadis[]

“return()”intheListmonadis[()]

Page 46: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Exampleof“guard”

[1..5]>>=\a->guard(isprimea)>>=\_->return(a+1)

doa<-[1..5]guard(isprimea)return(a+1)

guardTrue=[()]guardFalse=[]

=

= fa=guard(isprimea)>>=\_->return(a+1)reduceappnil(mapf[1,2,3,4,5])

= reduceappnil[guard(isprime1)>>\_return(1+1),guard(isprime2)>>\_return(2+1),guard(isprime3)>>\_return(3+1),guard(isprime4)>>\_return(4+1),guard(isprime5)>>\_return(5+1)]

Page 47: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Exampleof“guard”

doa<-[1..5]guard(isprimea)return(a+1)

guardTrue=[()]guardFalse=[]

=

=

=

reduceappnil[guardFalse>>\_return(1+1),guardTrue>>\_return(2+1),guardTrue>>\_return(3+1),guardFalse>>\_return(4+1),guardTrue>>\_return(5+1)]

reduceappnil[foldappnil(map(\_return(1+1))[]),foldappnil(map(\_return(2+1))[()]),foldappnil(map(\_return(3+1))[()]),foldappnil(map(\_return(4+1))[]),foldappnil(map(\_return(5+1))[()])]

reduceappnil[[],[2+1],[3+1],[][5+1]]

= [2+1,3+1,5+1] [2+1,3+1,5+1]= [3,4,6]=

Page 48: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Returningtothe“Pythagoreantriples”…

doa<-[1..25]b<-[a..25]c<-[b..25]guard(pabc)return(a,b,c)

Thisiscalleda“listcomprehension”

Inmonadiccomputa1on,inanycollec/onmonad(notjustList),guardservesasafilterforcomprehensions

Therewasnomagichere(exceptforlazyfunc1onalprogramming).Monads,“bind”,“guard”,theListmonad,

arealldefinedasuser-levelfunc1onsintheHaskelllanguageitself.

Page 49: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HASKELLEFFECTSINPUTANDOUTPUT

Page 50: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

I/OinHaskell•  Haskellhasaspecialkindofvaluecalledanac1onthat

describesaneffectontheworld

•  Pureac1ons,whichjustdosomethingandhavenointeres1ngresultarevaluesoftypeIO()

•  Eg:putStrtakesastringandyieldsanac1ondescribingtheactofdisplayingthisstringonstdout

--writesstringtostdoutputStr::String->IO()--writesstringtostdoutfollowedbynewlineputStrLn::String->IO()

Page 51: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

I/OinHaskell•  Whendoac1onsactuallyhappen?

•  Ac1onshappenundertwocircumstances:*1.  theac1ondefinedbymainhappenswhenyourprogramis

executed(ie:whenghccompilesyourprogramandthenyourunit)

2.  theac1ondefinedbyanyexpressionhappenswhenthatexpressioniswrihenattheghciinterpreterprompt(thisisprehysimilartothelastone–theexpressionisessen1alanen1reprogram)

*thereisoneothercircumstance:Haskellcontainssomespecial,unsafefunc1onsthatwillperformI/O,mostnotablySystem.IO.Unsafe.unsafePerformIOsoIliedwhenearlierwhenIsaidtheequa1onholdsingeneralforHaskellprograms...

Page 52: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

I/OinHaskell

main::IO()main=putStrLn“Helloworld”

hello.hs:

$ghchello.hs[1of1]CompilingMain(hello.hs,hello.o)Linkinghello.exe...$./hello.exehelloworld!

inmyshell:

Page 53: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

bar::Int->IO()barn=putStrLn(shown++“isasupernumber”)main::IO()main=bar6

bar.hs:

$ghcii.shGHCi,version7.0.3:hhp://www.haskell.org/ghc/:?forhelpLoadingpackageghc-prim...linking...done.Loadingpackageinteger-gmp...linking...done.Loadingpackagebase...linking...done.Loadingpackageffi-1.0...linking...done.Prelude>:lbar[1of1]CompilingMain(bar.hs,interpreted)Ok,modulesloaded:Main.*Main>bar1717isasupernumber*Main>main6isasupernumber*Main>

inmyshell:

Page 54: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Ac1ons•  Ac1onsaredescrip1onsofeffectsontheworld.Simply

wri1nganac1ondoesnot,byitselfcauseanythingtohappen

hellos::[IO()]hellos=[putStrLn“Hi”,putStrLn“Hey”,putStrLn“Topofthemorningtoyou”]main=hellos!!2

Prelude>:lhellos...*Main>mainTopofthemorningtoyou*Main>

bar.hs:

inmyshell:𝑙 !! 𝑛

gives 𝑛th element th element of list 𝑙

Page 55: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Ac1ons•  Ac1onsarejustlikeanyothervalue--wecanstorethem,

passthemtofunc1ons,rearrangethem,etc:

hellos::[IO()]hellos=[putStrLn“Hi”,putStrLn“Hey”,putStrLn“Topofthemorningtoyou”]main=sequence_(reversehellos)

Prelude>:lhellos...*Main>mainTopofthemorningtoyouHeyHI

baz.hs:

inmyshell:

sequence_::[IO()]->IO()

Page 56: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

CombiningAc1ons•  Theinfixoperator>>takestwoac1onsaandbandyieldsan

ac1onthatdescribestheeffectofexecu1ngathenexecu1ngbaZerward

•  Tocombinemanyac1ons,usedonota1on:

howdy::IO()howdy=putStr“how”>>putStrLn“dy”

bonjour::IO()bonjour=doputStr“Bonjour!”putStr“”putStrLn“Commentcava?”

Page 57: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

QuickAside:BacktoSEQEQ*•  Dowes1llhaveit?Yes!

leta=PutStrLn"hello"indoaa

doPutStrLn"hello"PutStrLn"hello"

=

*SEQEQ=subs1tu1onofequalsforequals

anac1onmadeupofdoingaandthendoingaagainwhereaisthePutStrLn"hello"ac1on

anac1onmadeupofdoingthePutStrLn"hello"ac1onandthendoingthePutStrLn"hello"ac1onagain

Page 58: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

InputAc1ons•  Someac1onshaveaneffectandyieldaresult:

•  Whatcanwedowiththesekindsofac1ons?–  wecanextractthevalueandsequencetheeffectwithanother:

--getalineofinputgetLine::IOString--getallofstandardinputun1lend-of-fileencounteredgetContents::IOString--getcommandlineargumentlistgetArgs::IO[String]

Page 59: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

InputAc1ons•  Someac1onshaveaneffectandyieldaresult:

•  Whatcanwedowiththesekindsofac1ons?–  wecanextractthevalueandsequencetheeffectwithanother:

--getalineofinputgetLine::IOString--getallofstandardinputun1lend-of-fileencounteredgetContents::IOString--getcommandlineargumentlistgetArgs::IO[String]

dos<-getLineputStrLns

Page 60: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

InputAc1ons•  Someac1onshaveaneffectandyieldaresult:

•  Whatcanwedowiththesekindsofac1ons?–  wecanextractthevalueandsequencetheeffectwithanother:

--getalineofinputgetLine::IOString--getallofstandardinputun1lend-of-fileencounteredgetContents::IOString--getcommandlineargumentlistgetArgs::IO[String]

dos<-getLineputStrLns

shastypestring getLinehastypeIOstring

Page 61: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

InputAc1ons•  Someac1onshaveaneffectandyieldaresult:

•  Whatcanwedowiththesekindsofac1ons?–  wecanextractthevalueandsequencetheeffectwithanother:

--getalineofinputgetLine::IOString--getallofstandardinputun1lend-of-fileencounteredgetContents::IOString--getcommandlineargumentlistgetArgs::IO[String]

dos<-getLineputStrLns

ThinkoftypeIOStringasaboxcontainingacomputa1onthatwilldosomeworkandthenproduceastring.getLineissuchabox.the<-getstheStringoutofthebox

s

The"do"packagesupthegetLineandtheputStrLnac1onsupintoabiggercompositebox

s

Page 62: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

InputAc1ons

main::IO()main=doputStrLn“What’syourname?”s<-getLineputStr“Hey,“putStrsputStrLn“,coolname!”

•  Awholeprogram:

Page 63: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

importSystem.IOimportSystem.EnvironmentprocessArgs::[String]->StringprocessArgs[a]=aprocessArgs_=""echo::String->IO()echo""=putStrLn"BadArgs!"echofileName=dos<-readFilefileNameputStrLn"Hereitis:"putStrLn"***********"putStrsputStrLn"\n***********"main::IO()main=doargs<-getArgsletfileName=processArgsargsechofileName

importmodules

containsreadFile

containsgetArgs,getProgName

<-nota1on:RHShastypeIOTLHShastypeT

letnota1on:RHShastypeTLHShastypeT

Page 64: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

SEQEQ(Again!)•  Recall:s1++s2concatenatesStrings1withStrings2•  Avalidreasoningstep:

lets="hello"indoputStrLn(s++s) = do

putStrLn("hello"++"hello")

Page 65: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

SEQEQ(Again!)•  Recall:s1++s2concatenatesStrings1withStrings2•  Avalidreasoningstep:

•  Avalidreasoningstep:

lets="hello"indoputStrLn(s++s) = do

putStrLn("hello"++"hello")

=dolets="hello"putStrLn(s++s)

doputStrLn("hello"++"hello")

Page 66: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

SEQEQ(Again!)•  Recall:s1++s2concatenatesStrings1withStrings2•  Avalidreasoningstep:

•  Avalidreasoningstep:

•  Wait,whataboutthis:

lets="hello"indoputStrLn(s++s) = do

putStrLn("hello"++"hello")

=dolets="hello"putStrLn(s++s)

doputStrLn("hello"++"hello")

dos<-getLineputStrLn(s++s)

doputStrLn(getLine++getLine)≠

wrongtype:getLine::IOString

Page 67: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

SEQEQ(Again!)•  Invalidreasoningstep?

lets=getLineindoputStrLn(s++s)

doputStrLn(getLine++getLine)=?

Page 68: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

SEQEQ(Again!)•  Invalidreasoningstep?

lets=getLineindoputStrLn(s++s)

doputStrLn(getLine++getLine)

wrongtype:s::IOString

wrongtype:getLine::IOString

=?

Page 69: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

SEQEQ(Again!)•  Invalidreasoningstep?

•  TheHaskelltypesystemshowsx<-eisdifferentfromletx=e

–  xhasadifferenttypeineachcase–  letx=eenablessubs1tu1onofeforxinwhatfollows–  x<-edoesnotenablesubs1tu1on--ahemp1ngsubs1tu1onleavesyouwithcodethatwon'teventypecheckbecausexandehavedifferenttypes(typeTvs.typeIOT)

lets=getLineindoputStrLn(s++s)

doputStrLn(getLine++getLine)

wrongtype:s::IOString

wrongtype:getLine::IOString

=?

Page 70: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Magic?TheListmonadwasnot“magic.”Listcomprehensions,“iterators”,guards,couldallbeexpressedinthepurefunc1onallanguagewithnomagicextensions.TheIOmonadismagic.Butallthemonadiccombinatorsformanipula1ngit,sequencing,etc.,arenotmagic;theyareexpressibleinthepurefunc1onallanguage.

Page 71: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HASKELLEFFECTS:REFERENCES

Page 72: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ComingBacktoReferencesAgain•  RememberthisOCamlfunc1on:

•  Weno1cedthat:

•  WhatifwewritesomethingsimilarinHaskell?

letx=ref0letfoo(y:int):int=x:=!x+1;arg+!x;

lety=foo3iny+y ≠ foo3+foo3

foo:int->int

:int

Page 73: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ComingBacktoReferencesAgain•  RememberthisOCamlfunc1on:

•  Weno1cedthat:

•  WhatifwewritesomethingsimilarinHaskell?

letx=ref0letfoo(y:int):int=x:=!x+1;arg+!x;

lety=foo3iny+y ≠ foo3+foo3

foo:int->int

:int

x::Refintfoo::int->intfooy=x:=readx+1;arg+!x;

doesn'ttypecheck

Page 74: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HaskellTypesTellYouWheretheEffectsAren't!

foo :: int -> int

Haskellfunc/ontypesarepure--totallyeffect-free

Haskell’stypesystemforces*purityonfunc1onswithtypea -> b •  noprin1ng•  nomutabledata•  noreadingfromfiles•  noconcurrency•  nobenigneffects(likememoiza1on)

*exceptforunsafePerformIO

exp :: int Samewithexpressions.Expressionswithjusttypeinthavenoeffect!

Page 75: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

foo :: int -> int totallypurefunc/on

<code> :: IO int

suspended(lazy)computa/onthatperformseffectswhenexecuted

HaskellTypesTellYouWheretheEffectsAren't!

Page 76: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

foo :: int -> int totallypurefunc/on

<code> :: IO int

suspended(lazy)computa/onthatperformseffectswhenexecuted

bar :: int -> IO int totallypurefunc/onthatreturnssuspendedeffec@ulac/on

HaskellTypesTellYouWheretheEffectsAren't!

Page 77: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

print :: string -> IO ()

reverse :: string -> string

reverse “hello” :: string

print (reverse “hello”) :: IO ()

thetypesystemalwaystellsyouwhenaneffecthashappened–effectscan’t“escape”theI/Omonad

HaskellTypesTellYouWheretheEffectsAren't!

Page 78: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

References

read :: Ref a -> IO a

(+) :: int -> int -> int

r :: Ref int

(read r) + 3 :: int

Doesn’t type check

Page 79: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

References

read :: Ref a -> IO a

(+) :: int -> int -> int

r :: Ref int

do

x <- read r return (x + 3)

the"return"ac1onhasnoeffect;itjustreturnsitsvalue

createsacomposi1onac1onthatreadsareferenceandproducesthevalueinthatreferenceplus3

Page 80: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

MutableState

Haskellusesnew,read,andwrite*func1onswithintheIOMonadtomanagemutablestate.

main = do r <- new 0 -- let r = ref 0 in inc r -- r := !r+1; s <- read r -- s := !r; print s

inc :: Ref Int -> IO () inc r = do

v <- read r -- v := !r

write r (v+1) -- r := !v +1

new :: a -> IO (Ref a) read :: Ref a -> IO a write :: Ref a -> a -> IO ()

*actuallynewRef,readRef,writeRef,…

Page 81: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

MONADS

Page 82: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

TheBiggerPicture•  Haskell'stypesystem(atleastthepartofitthatwehaveseen

sofar)isverysimilartotheMLtypesystem–  eg:typingrulesforpureprimi1ves(func1ons,pairs,lists,etc)aresimilarinbothcases:•  iff:t1->t2ande:t1then(fe):t2•  ife1:t1ande2:t2then(e1,e2):(t1,t2)

•  WhatHaskellhasdonethatisspecialis:

–  ithasbeenverycarefultogiveeffec�ulprimi1vesspecialtypesinvolving"IOt"

–  allowscomposi1onofac1onswithtype"IOt"•  theIOdatatype+itscomposi1onfunc1onsarecalledamonad

–  ithassyntaxforprogrammingwithmonads(donota1on)–  MLcoulddothosethingstoo(ie:thesedecisionsdonotdependuponalanguagehavelazyevalua1on)

Page 83: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Wecantalkaboutwhatmonadsarebyreferringtotheirinterface

Recallaninterfacedeclaressomenewabstracttypesandsomeopera1onsovervalueswiththoseabstracttypes.Forexample:

moduletypeCONTAINER=sigtype‘at(*thetypeofthecontainer*)valempty:‘atvalinsert:‘a->‘at->‘atvalremove:‘at->‘aop1on*‘atvalfold:(‘a->‘b->‘b)->‘b->‘at->‘bend

There are lots of different implementations of such containers: queues, stacks, sets, randomized sets, ...

Page 84: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Wecantalkaboutwhatmonadsarebyreferringtotheirinterface

Recallaninterfacedeclaressomenewabstracttypesandsomeopera1onsovervalueswiththoseabstracttypes.Forexample:

moduletypeCONTAINER=sigtype‘at(*thetypeofthecontainer*)valempty:‘atvalinsert:‘a->‘at->‘atvalremove:‘at->‘aop1on*‘atvalfold:(‘a->‘b->‘b)->‘b->‘at->‘bend

There are lots of different implementations of such containers: queues, stacks, sets, randomized sets, ...

Interfaces can come with some equations one expects every implementation to satisfy. eg:

fold f base empty == base

The equations specify some, but not all of the behavior of the module (eg: stacks and queues remove elements in different orders)

Page 85: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

MonadsAmonadisjustapar1cularinterface.Twoviews:

–  (1)interfaceforaverygenericcontainer,withopera1onsdesignedtosupportcomposi/onofcomputa1onsoverthecontentsofcontainers

–  (2)interfaceforanabstractcomputa1onthatdoessome“bookkeeping”ontheside.By“bookkeeping”wemean“effects”.Onceagain,thesupportforcomposi1oniskey.

–  sincefunc1onalprogrammersknowthatfunc1onsaredata,thetwoviewsactuallycoincide

Page 86: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

MonadsAmonadisjustapar1cularinterface.Twoviews:–  (1)interfaceforaverygenericcontainer

•  supportscomposi/onofcomputa1onsoverthecontentsofcontainers

–  (2)interfaceforanabstractcomputa1onthatdoessome“bookkeeping.”•  bookkeepingiscodefor“hasaneffect”.Onceagain,thesupportforcomposi1oniskey.

–  sincefunc1onalprogrammersknowthatfunc1onsaredata,thetwoviewsactuallycoincide

Manydifferentkindsofmonads:–  monadsforhandling/accumula1ngerrors–  monadsforprocessingcollec1onsenmasse–  monadsforloggingstringsthatshouldbeprinted–  monadsforcoordina1ngconcurrentthreads(seeOCamlAsynclibrary)–  monadsforbacktrackingsearch–  monadsfortransac/onalmemory

Page 87: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

MonadsAmonadisjustapar1cularinterface.Twoviews:–  (1)interfaceforaverygenericcontainer

•  supportscomposi/onofcomputa1onsoverthecontentsofcontainers

–  (2)interfaceforanabstractcomputa1onthatdoessome“bookkeeping.”•  bookkeepingiscodefor“hasaneffect”.Onceagain,thesupportforcomposi1oniskey.

–  sincefunc1onalprogrammersknowthatfunc1onsaredata,thetwoviewsactuallycoincide

Becauseamonadisjustapar1cularinterface(withmanyusefulimplementa1ons),youcanimplementmonadsinanylanguage–  But,Haskellisfamousforthembecauseithasaspecialbuilt-insyntaxthat

makesmonadspar1cularlyeasyandeleganttouse–  F#,Scalahaveadoptedsimilarsyntac1cideas–  MonadsalsoplayaveryspecialroleintheoveralldesignoftheHaskell

languageduetotheconfinementofeffects•  Monadsaretherightwaytoenablebotheffectsandsubs1tu1onofequalsforequals

Page 88: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Whatisthemonadinterface?

+someequa1onsspecifyinghowreturnandbindarerequiredtointeract

Considerfirstthe“containerinterpreta1on”:

§  ‘aMisacontainerforvalueswithtype‘a

§  returnxputsxinthecontainer

§  bindcftakesthevaluesincoutofthecontainerandappliesftothem,forminganewcontainerholdingtheresults

-  bindcfisoZenwrihenas:c>>=f

moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

Page 89: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

TheOp1onsasaContainer

moduleOp1onMonad=structtype‘aM=‘aop1onletreturnx=Somexlet(>>=)cf=matchcwithNone->None|Somev->fvend

put value ina containertake value v out

of a container cand then apply f, producing a new container

moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

Page 90: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

TheOp1onsasaContainer

typefile_name=stringvalread_file:file_name->stringMletconcatf1f2=readfilef1 >>=(funcontents1->readfilef2 >>=(funcontents2->return(contents1^contents2)

put value ina containertake value v out

of a container cand then apply f, producing a new container

using the option container:

moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

moduleOp1onMonad=structtype‘aM=‘aop1onletreturnx=Somexlet(>>=)cf=matchcwithNone->None|Somev->fvend

Page 91: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Book-keepingInterpreta1on:TheOp1onMonadasPossiblyErroneousComputa1on

moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

moduleErrorMonad=structtype‘aM=‘aop1onletreturnx=Somexlet(>>=)cf=matchcwithNone->None|Somev->fvendtypefile_name=string

valread_file:file_name->stringMletconcatf1f2=readfilef1 >>=(funcontents1->readfilef2 >>=(funcontents2->return(contents1^contents2)

setting upbookkeepingfor error processing

compose bookkeeping:check to see iferror has occurred, if so return None,else continue

using the error monad:

Page 92: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListsasContainers

moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

moduleListMonad=structtype‘aM=‘alistletreturnx=[x]let(>>=)cf=List.flahen(List.mapfc)end

random_sample:unit->intMmonte_carlo:int->int->int->resultletexperiments:resultM=random_sample()>>=(funs1->random_sample()>>=(funs2->random_sample()>>=(funs3->return(monte_carlos1s2s3)

put elementinto listcontainer

apply f to all elements of the list c, creating a list of lists and then flatten results in to single list

using the list monad:

Page 93: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

ListsasContainers

moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

moduleListMonad=structtype‘aM=‘alistletreturnx=[x]let(>>=)cf=List.flahen(List.mapfc)end

random_sample:unit->intMmonte_carlo:int->int->int->resultletexperiments:resultM=random_sample()>>=(funs1->random_sample()>>=(funs2->random_sample()>>=(funs3->return(monte_carlos1s2s3)

using the list monad:

one result;no nondeterminismcompose many

possible results (c)with a nondeterministiccontinuation f

Page 94: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

AContainerwithaStringontheSide(aka:Alogging/prin1ngmonad)

moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

moduleLoggingMonad=structtype‘aM=‘a*stringletreturnx=(x,“”)let(>>=)cf=let(v,s)=cinlet(v’,s’)=fvin(v’,s^s’)endrecord:(‘a->‘b)->‘a->string->‘bM

letrecordfxs=(fx,s)letdox=recordreadx“readit”>>=(funv->recordwritev“wroteit”>>=(fun_->recordwritev“wroteitagain”>>=(fun_->returnv

nothing loggedyetconcatenate the

log of c withthe log producedby running f

using the logging monad:

Page 95: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

AContainerwithaStateontheSide(aka:Alogging/prin1ngmonad)

moduletypeMONAD=sigtype‘aMvalreturn:‘a->‘aMval(>>=):‘aM->(‘a->‘bM)->‘bMend

moduleStateMonad=structtypestate=addressintmaptype‘aM=‘a*(state->state)letreturnx=???let(>>=)cf=???letreada=???letwriteav=???end

Page 96: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

MonadLawsJustlikeoneexpectsanyCONTAINERtobehaveinapar1cularway,onehasexpecta1onsofMONADs.LeZiden1ty:“returndoesnothingobservable”(1)  returnv>>=f==fv

Rightiden1ty:“returns1lldoesn’tdoanythingobservable”(2)m>>=return==mAssocia1vity:“composingmwithffirstandthendoinggisthesameasdoingmwiththecomposi1onoffandg”(3)(m>>=f)>>=g==m>>=(funx->fx>>=g)

Page 97: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

BreakingtheLawJustlikeoneexpectsanyCONTAINERtobehaveinapar1cularway,onehasexpecta1onsofMONADs.LeZiden1ty:“returndoesnothingobservable”(1)  returnv>>=f==fv

module LoggingMonad = struct type ‘a M = ‘a * string let return x = (x, “start”) let (>>=) c f = let (v, s) = c in let (v’,s’) = f v in (v’, s ^ s’) end

return 3 >>= fun x -> return x == (3,”start”) >>= fun x -> return x == (3, “start” ^ “start”) == (3, “startstart”)

(fun x -> return x) 3 == return 3 == (3, “start”)

Page 98: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

BreakingtheLawWhataretheconsequencesofbreakingthelaw?Well,ifyoutoldyourfriendyou’veimplementedamonadandtheycanuseitinyourcode,theywillexpectthattheycanrewritetheircodeusingequa1onslikethisone:returnx>>=f==fxIfyoutellyourfriendyou’veimplementedthemonadinterfacebutnoneofthemonadlawsholdyourfriendwillprobablysay:Ok,tellmewhatyourfunc1onsdothenandpleasestopusingthewordmonadbecauseitisconfusing.ItislikeyouareclaimingtohaveimplementedtheQUEUEinterfacebutinsertandremoveareFirst-In,First-Outlikeastack.InHaskellorF#orScala,breakingthemonadlawsmayhavemoresevereconsequences,becausethecompileractuallyusesthoselawstodosometransforma1onsofyourcode.

Page 99: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

HASKELLWRAPUP

BynowyoushouldappreciatethesignificanceofHaskell’slogo,combiningthelambdaλandthemonadicbindoperator>>=.

Page 100: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

AMonadicSkin

InlanguageslikeMLorJava,thereisnowaytodis1nguishbetween:–  purefunc1onswithtypeint->int–  effec�ulfunc1onswithtypeint->int

InHaskell,theprogrammercanchoosewhentoliveintheIOmonadandwhentoliveintherealmofpurefunc1onalprogramming.

–  Counter-point:Wehaveshownthatitisusefultobeabletobuildpureabstrac1onsusingimpera1veinfrastructure(eg:laziness,futures,parallelsequences,memoiza1on).Youcan’tdothatinHaskell(withoutescapingthetypesystemviaunsafeI0)

Interes1ngperspec1ve:ItisnotHaskellthatlacksimpera1vefeatures,butrathertheotherlanguagesthatlacktheabilitytohaveasta1callydis1nguishablepuresubset.

Acheckedpure-impuresepara1onfacilitatesreasoningaboutprograms,especiallyconcurrentones.

Page 101: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

TheCentralChallenge

Arbitrary effects

No effects

Safe

Useful

Useless

Dangerous

Page 102: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

TheChallengeofEffects

Arbitrary effects

No effects

Useful

Useless

Dangerous Safe

Nirvana

Plan A �(everyone else)

Plan B �(Haskell)

Page 103: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

TwoBasicApproaches:PlanA

Examples•  Regions•  Ownershiptypes•  Rust

–  followingfromresearchlanguageslikeVault,Spec#,Cyclone

Arbitrary effects

Default = Any effect �Plan = Add restrictions

Page 104: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

TwoBasicApproaches:PlanB

Twomainapproaches:•  Domainspecificlanguages

(SQL,Xquery,Googlemap/reduce)

•  Wide-spectrumfunc1onallanguages+controlledeffects(e.g.Haskell)

Value oriented programming

Types play a major role

Default = No effects�Plan = Selectively permit effects

Page 105: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

LotsofCrossOver

Arbitrary effects

No effects

Useful

Useless

Dangerous Safe

Nirvana

Plan A �(everyone else)

Plan B �(Haskell)

Envy

accordingtoSimonPeytonJones

Page 106: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

LotsofCrossOver

Arbitrary effects

No effects

Useful

Useless

Dangerous Safe

Nirvana

Plan A �(everyone else)

Plan B �(Haskell)

Ideas; e.g. Software Transactional Memory

Page 107: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

Arewethereyet?

No effects

Useful

Useless

Dangerous Safe

Nirvana

Plan B �(Haskell)

IsHaskellhere?

Orhere?

Someissues:

•  Can’tencapsulateeffec�ulcomputa1oninsidepure-

func1onaltypes.

•  Lazythunkscangiveaperformancepenalty

Page 108: Haskell - cs.princeton.edu · Haskell Another cool, typed, func1onal programming language • Like OCaml in that: – it is a func1onal language with parametric polymorphism • Unlike

AnAssessmentandaPredic1on

One of Haskell’s most significant contributions is to take purity seriously, and relentlessly pursue Plan B. Imperative languages will embody growing (and checkable) pure subsets.

-- Simon Peyton Jones