You are on page 1of 31

Typeclassopedia

FromHaskellWiki
ByBrentYorgey,byorgey@cis.upenn.edu
Originallypublished12March2009inissue13(http://www.haskell.org/wikiupload/8/85/TMRIssue13.pdf)oftheMonad.Reader
(http://themonadreader.wordpress.com/).PortedtotheHaskellwikiinNovember2011byGeheimdienst.
ThisisnowtheofficialversionoftheTypeclassopediaandsupersedestheversionpublishedintheMonad.Reader.Pleasehelpupdateandextendit
byeditingityourselforbyleavingcomments,suggestions,andquestionsonthetalkpage.

Contents
1Abstract
2Introduction
3Functor
3.1Definition
3.2Instances
3.3Laws
3.4Intuition
3.5Furtherreading
4Applicative
4.1Definition
4.2Laws
4.3Instances
4.4Intuition
4.5Alternativeformulation
4.6Furtherreading
5Monad
5.1Definition
5.2Instances
5.3Intuition
5.4Utilityfunctions
5.5Laws
5.6donotation
5.7Furtherreading
6Monadtransformers
6.1Standardmonadtransformers
6.2Definitionandlaws
6.3Transformertypeclassesand"capability"style
6.4Composingmonads
6.5Furtherreading
7MonadFix
7.1mdo/dorecnotation
7.2Examplesandintuition
7.3GHC7.6changes
7.4Furtherreading
8Semigroup
8.1Definition
8.2Laws
9Monoid
9.1Definition
9.2Laws
9.3Instances
9.4Othermonoidalclasses:Alternative,MonadPlus,ArrowPlus
9.5Furtherreading
10Foldable
10.1Definition
10.2Instancesandexamples
10.3Derivedfolds
10.4Foldableactuallyisn't
10.5Furtherreading
11Traversable

11.1Definition
11.2Intuition
11.3Instancesandexamples
11.4Laws
11.5Furtherreading
12Category
12.1Furtherreading
13Arrow
13.1Definition
13.2Intuition
13.3Instances
13.4Laws
13.5ArrowChoice
13.6ArrowApply
13.7ArrowLoop
13.8Arrownotation
13.9Furtherreading
14Comonad
14.1Definition
14.2Furtherreading
15Acknowledgements
16Abouttheauthor
17Colophon

1Abstract
ThestandardHaskelllibrariesfeatureanumberoftypeclasseswithalgebraicorcategorytheoreticunderpinnings.BecomingafluentHaskell
hackerrequiresintimatefamiliaritywiththemall,yetacquiringthisfamiliarityofteninvolvescombingthroughamountainoftutorials,blogposts,
mailinglistarchives,andIRClogs.
ThegoalofthisdocumentistoserveasastartingpointforthestudentofHaskellwishingtogainafirmgraspofitsstandardtypeclasses.The
essentialsofeachtypeclassareintroduced,withexamples,commentary,andextensivereferencesforfurtherreading.

2Introduction
Haveyoueverhadanyofthefollowingthoughts?
Whattheheckisamonoid,andhowisitdifferentfromamonad?
IfinallyfiguredouthowtouseParsecwithdonotation,andsomeonetoldmeIshouldusesomethingcalledApplicativeinstead.Um,what?
Someoneinthe#haskellIRCchannelused(***),andwhenIaskedLambdabottotellmeitstype,itprintedoutscarygobbledygookthat
didntevenfitononeline!Thensomeoneusedfmapfmapfmapandmybrainexploded.
WhenIaskedhowtodosomethingIthoughtwasreallycomplicated,peoplestartedtypingthingslikezip.apfmap.(id&&&wtf)andthe
scarythingisthattheyworked!Anyway,Ithinkthosepeoplemustactuallyberobotsbecausetheresnowayanyonecouldcomeupwith
thatintwosecondsoffthetopoftheirhead.
Ifyouhave,looknofurther!You,too,canwriteandunderstandconcise,elegant,idiomaticHaskellcodewiththebestofthem.
TherearetwokeystoanexpertHaskellhackerswisdom:
1. Understandthetypes.
2. Gainadeepintuitionforeachtypeclassanditsrelationshiptoothertypeclasses,backedupbyfamiliaritywithmanyexamples.
Itsimpossibletooverstatetheimportanceofthefirstthepatientstudentoftypesignatureswilluncovermanyprofoundsecrets.Conversely,
anyoneignorantofthetypesintheircodeisdoomedtoeternaluncertainty.Hmm,itdoesntcompile...maybeIllstickinanfmaphere...nope,
letssee...maybeIneedanother(.)somewhere?...um...
Thesecondkeygainingdeepintuition,backedbyexamplesisalsoimportant,butmuchmoredifficulttoattain.Aprimarygoalofthis
documentistosetyouontheroadtogainingsuchintuition.However
ThereisnoroyalroadtoHaskell.Euclid
Thisdocumentcanonlybeastartingpoint,sincegoodintuitioncomesfromhardwork,notfromlearningtherightmetaphor

(http://byorgey.wordpress.com/2009/01/12/abstractionintuitionandthemonadtutorialfallacy/).Anyonewhoreadsandunderstandsallofitwill
stillhaveanarduousjourneyaheadbutsometimesagoodstartingpointmakesabigdifference.
ItshouldbenotedthatthisisnotaHaskelltutorialitisassumedthatthereaderisalreadyfamiliarwiththebasicsofHaskell,includingthe
standardPrelude(http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html),thetypesystem,datatypes,andtypeclasses.
Thetypeclasseswewillbediscussingandtheirinterrelationships:

Solidarrowspointfromthegeneraltothespecificthatis,ifthereisanarrowfromFootoBaritmeans
thateveryBaris(orshouldbe,orcanbemadeinto)aFoo.
Dottedarrowsindicatesomeothersortofrelationship.
MonadandArrowApplyareequivalent.
Semigroup,ApplyandComonadaregreyedoutsincetheyarenotactually(yet?)inthestandardHaskell
libraries .

Semigroupcanbefoundin
thesemigroupspackage
(http://hackage.haskell.org/package/sem
,Applyinthesemigroupoids
package
(http://hackage.haskell.org/package/sem
,andComonadinthecomonad
package
(http://hackage.haskell.org/package/com
.

Onemorenotebeforewebegin.Theoriginalspellingoftypeclassiswithtwowords,asevidencedby,for
example,theHaskell2010LanguageReport(http://www.haskell.org/onlinereport/haskell2010/),earlypapers
ontypeclasseslikeTypeclassesinHaskell(http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.103.5639)
andTypeclasses:exploringthedesignspace(http://research.microsoft.com/en
us/um/people/simonpj/papers/typeclassdesignspace/),andHudaketal.shistoryofHaskell
(http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.168.4008).However,asoftenhappenswithtwoword
phrasesthatseealotofuse,ithasstartedtoshowupasoneword(typeclass)or,rarely,hyphenated(typeclass).Whenwearingmy
prescriptivisthat,Iprefertypeclass,butrealize(afterchangingintomydescriptivisthat)thatthere'sprobablynotmuchIcandoaboutit.
Wenowbeginwiththesimplesttypeclassofall:Functor.

3Functor
TheFunctorclass(haddock(http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor))isthemostbasicandubiquitous
typeclassintheHaskelllibraries.AsimpleintuitionisthataFunctorrepresentsacontainerofsomesort,alongwiththeabilitytoapplya
functionuniformlytoeveryelementinthecontainer.Forexample,alistisacontainerofelements,andwecanapplyafunctiontoeveryelementof
alist,usingmap.Asanotherexample,abinarytreeisalsoacontainerofelements,anditsnothardtocomeupwithawaytorecursivelyapplya
functiontoeveryelementinatree.
AnotherintuitionisthataFunctorrepresentssomesortofcomputationalcontext.Thisintuitionisgenerallymoreuseful,butismoredifficultto
explain,preciselybecauseitissogeneral.SomeexampleslatershouldhelptoclarifytheFunctorascontextpointofview.
Intheend,however,aFunctorissimplywhatitisdefinedtobedoubtlesstherearemanyexamplesofFunctorinstancesthatdontexactlyfit
eitheroftheaboveintuitions.Thewisestudentwillfocustheirattentionondefinitionsandexamples,withoutleaningtooheavilyonanyparticular
metaphor.Intuitionwillcome,intime,onitsown.

3.1Definition
HereisthetypeclassdeclarationforFunctor:
classFunctorfwhere
fmap::(a>b)>fa>fb
FunctorisexportedbythePrelude,sonospecialimportsareneededtouseit.

First,thefaandfbinthetypesignatureforfmaptellusthatfisntjustatypeitisatypeconstructorwhichtakesanothertypeasaparameter.(A

moreprecisewaytosaythisisthatthekindoffmustbe*>*.)Forexample,Maybeissuchatypeconstructor:Maybeisnotatypeinandofitself,
butrequiresanothertypeasaparameter,likeMaybeInteger.SoitwouldnotmakesensetosayinstanceFunctorInteger,butitcouldmakesense
tosayinstanceFunctorMaybe.
Nowlookatthetypeoffmap:ittakesanyfunctionfromatob,andavalueoftypefa,andoutputsavalueoftypefb.Fromthecontainerpointof
view,theintentionisthatfmapappliesafunctiontoeachelementofacontainer,withoutalteringthestructureofthecontainer.Fromthecontext
pointofview,theintentionisthatfmapappliesafunctiontoavaluewithoutalteringitscontext.Letslookatafewspecificexamples.

3.2Instances
Asnotedbefore,thelistconstructor[]isafunctor wecanusethestandardlistfunctionmaptoapplya
functiontoeachelementofalist .TheMaybetypeconstructorisalsoafunctor,representingacontainer
whichmightholdasingleelement.ThefunctionfmapghasnoeffectonNothing(therearenoelementstowhich
gcanbeapplied),andsimplyappliesgtothesingleelementinsideaJust.Alternatively,underthecontext
interpretation,thelistfunctorrepresentsacontextofnondeterministicchoicethatis,alistcanbethoughtofas
representingasinglevaluewhichisnondeterministicallychosenfromamongseveralpossibilities(theelements
ofthelist).Likewise,theMaybefunctorrepresentsacontextwithpossiblefailure.Theseinstancesare:
instanceFunctor[]where
fmap_[]=[]
fmapg(x:xs)=gx:fmapgxs
orwecouldjustsayfmap=map

instanceFunctorMaybewhere
fmap_Nothing=Nothing
fmapg(Justa)=Just(ga)

Asanaside,inidiomaticHaskellcodeyouwilloftenseetheletterfusedtostandforbothanarbitraryFunctor
andanarbitraryfunction.Inthisdocument,frepresentsonlyFunctors,andgorhalwaysrepresentfunctions,
butyoushouldbeawareofthepotentialconfusion.Inpractice,whatfstandsforshouldalwaysbeclearfrom
thecontext,bynotingwhetheritispartofatypeorpartofthecode.
ThereareotherFunctorinstancesinthestandardlibrariesbelowareafew.Notethatsomeoftheseinstances
arenotexportedbythePreludetoaccessthem,youcanimportControl.Monad.Instances.
EithereisaninstanceofFunctorEitherearepresentsacontainerwhichcancontaineitheravalueof
typea,oravalueoftypee(oftenrepresentingsomesortoferrorcondition).ItissimilartoMaybeinthatit

Recallthat[]hastwo
meaningsinHaskell:itcan
eitherstandfortheemptylist,
or,ashere,itcanrepresent
thelisttypeconstructor
(pronouncedlistof).In
otherwords,thetype[a]
(listofa)canalsobewritten
[]a.
Youmightaskwhywe
needaseparatemapfunction.
Whynotjustdoawaywith
thecurrentlistonlymap
function,andrenamefmapto
mapinstead?Well,thatsa
goodquestion.Theusual
argumentisthatsomeonejust
learningHaskell,whenusing
mapincorrectly,wouldmuch
ratherseeanerroraboutlists
thanaboutFunctors.

representspossiblefailure,butitcancarrysomeextrainformationaboutthefailureaswell.
((,)e)representsacontainerwhichholdsanannotationoftypeealongwiththeactualvalueitholds.Itmightbeclearertowriteitas
(e,),byanalogywithanoperatorsectionlike(1+),butthatsyntaxisnotallowedintypes(althoughitisallowedinexpressionswiththe
TupleSectionsextensionenabled).However,youcancertainlythinkofitas(e,).
((>)e)(whichcanbethoughtofas(e>)seeabove),thetypeoffunctionswhichtakeavalueoftypeeasaparameter,isaFunctor.Asa
container,(e>a)representsa(possiblyinfinite)setofvaluesofa,indexedbyvaluesofe.Alternatively,andmoreusefully,((>)e)can
bethoughtofasacontextinwhichavalueoftypeeisavailabletobeconsultedinareadonlyfashion.Thisisalsowhy((>)e)is

sometimesreferredtoasthereadermonadmoreonthislater.
IOisaFunctoravalueoftypeIOarepresentsacomputationproducingavalueoftypeawhichmayhaveI/Oeffects.Ifmcomputesthe
valuexwhileproducingsomeI/Oeffects,thenfmapgmwillcomputethevaluegxwhileproducingthesameI/Oeffects.

Manystandardtypesfromthecontainerslibrary(http://hackage.haskell.org/package/containers/)(suchasTree,Map,andSequence)are
instancesofFunctor.AnotableexceptionisSet,whichcannotbemadeaFunctorinHaskell(althoughitiscertainlyamathematicalfunctor)
sinceitrequiresanOrdconstraintonitselementsfmapmustbeapplicabletoanytypesaandb.However,Set(andothersimilarlyrestricted
datatypes)canbemadeaninstanceofasuitablegeneralizationofFunctor,eitherbymakingaandbargumentstotheFunctortypeclass
themselves(http://article.gmane.org/gmane.comp.lang.haskell.cafe/78052/),orbyaddinganassociatedconstraint(http://blog.omega
prime.co.uk/?p=127).
Exercises
1. ImplementFunctorinstancesforEithereand((>)e).
2. ImplementFunctorinstancesfor((,)e)andforPair,definedas
dataPaira=Pairaa

Explaintheirsimilaritiesanddifferences.
3. ImplementaFunctorinstanceforthetypeITree,definedas
dataITreea=Leaf(Int>a)
|Node[ITreea]

4. Giveanexampleofatypeofkind*>*whichcannotbemadean
instanceofFunctor(withoutusingundefined).
5. Isthisstatementtrueorfalse?
ThecompositionoftwoFunctorsisalsoaFunctor.
Iffalse,giveacounterexampleiftrue,proveitbyexhibitingsome
appropriateHaskellcode.

3.3Laws
AsfarastheHaskelllanguageitselfisconcerned,theonlyrequirementtobeaFunctorisanimplementationoffmapwiththepropertype.Any
sensibleFunctorinstance,however,willalsosatisfythefunctorlaws,whicharepartofthedefinitionofamathematicalfunctor.Therearetwo:
fmapid=id
fmap(g.h)=(fmapg).(fmaph)

Together,theselawsensurethatfmapgdoesnotchangethestructureofacontainer,onlytheelements.
Equivalently,andmoresimply,theyensurethatfmapgchangesavaluewithoutalteringitscontext .
Thefirstlawsaysthatmappingtheidentityfunctionovereveryiteminacontainerhasnoeffect.Thesecond
saysthatmappingacompositionoftwofunctionsovereveryiteminacontaineristhesameasfirstmappingone
function,andthenmappingtheother.
Asanexample,thefollowingcodeisavalidinstanceofFunctor(ittypechecks),butitviolatesthefunctor
laws.Doyouseewhy?

Technically,theselaws
makefandfmaptogetheran
endofunctoronHask,the
categoryofHaskelltypes
(ignoring,whichisaparty
pooper).SeeWikibook:
Categorytheory
(http://en.wikibooks.org/wiki/Haskell/C
.

EvilFunctorinstance
instanceFunctor[]where
fmap_[]=[]
fmapg(x:xs)=gx:gx:fmapgxs

AnyHaskellerworththeirsaltwouldrejectthiscodeasagruesomeabomination.
Unlikesomeothertypeclasseswewillencounter,agiventypehasatmostonevalidinstanceofFunctor.Thiscanbeproven
(http://article.gmane.org/gmane.comp.lang.haskell.libraries/15384)viathefreetheorem
(http://homepages.inf.ed.ac.uk/wadler/topics/parametricity.html#free)forthetypeoffmap.Infact,GHCcanautomaticallyderive
(http://byorgey.wordpress.com/2010/03/03/derivingpleasurefromghc6121/)Functorinstancesformanydatatypes.
Asimilarargumentalsoshows(https://github.com/quchen/articles/blob/master/second_functor_law.md)that
anyFunctorinstancesatisfyingthefirstlaw(fmapid=id)willautomaticallysatisfythesecondlawaswell.
Practically,thismeansthatonlythefirstlawneedstobechecked(usuallybyaverystraightforwardinduction)
toensurethataFunctorinstanceisvalid.
Exercises
1. AlthoughitisnotpossibleforaFunctorinstancetosatisfythefirst
Functorlawbutnotthesecond(excludingundefined),thereverse
ispossible.Giveanexampleofa(bogus)Functorinstancewhich
satisfiesthesecondlawbutnotthefirst.
2. WhichlawsareviolatedbytheevilFunctorinstanceforlistshown
above:bothlaws,orthefirstlawalone?Givespecific
counterexamples.

Actually,ifseq/undefined
areconsidered,itispossible
(http://stackoverflow.com/a/8323243/30
tohaveanimplementation
whichsatisfiesthefirstlaw
butnotthesecond.Therest
ofthecommentsinthis
sectionshouldconsideredin
acontextwhereseqand
undefinedareexcluded.

3.4Intuition
Therearetwofundamentalwaystothinkaboutfmap.Thefirsthasalreadybeenmentioned:ittakestwoparameters,afunctionandacontainer,and
appliesthefunctioninsidethecontainer,producinganewcontainer.Alternately,wecanthinkoffmapasapplyingafunctiontoavalueina
context(withoutalteringthecontext).
JustlikeallotherHaskellfunctionsofmorethanoneparameter,however,fmapisactuallycurried:itdoesnotreallytaketwoparameters,but
takesasingleparameterandreturnsafunction.Foremphasis,wecanwritefmapstypewithextraparentheses:fmap::(a>b)>(fa>fb).
Writteninthisform,itisapparentthatfmaptransformsanormalfunction(g::a>b)intoonewhichoperatesovercontainers/contexts(fmap
g::fa>fb).Thistransformationisoftenreferredtoasaliftfmapliftsafunctionfromthenormalworldintothefworld.

3.5Furtherreading
AgoodstartingpointforreadingaboutthecategorytheorybehindtheconceptofafunctoristheexcellentHaskellwikibookpageoncategory
theory(http://en.wikibooks.org/wiki/Haskell/Category_theory).

4Applicative
AsomewhatneweradditiontothepantheonofstandardHaskelltypeclasses,applicativefunctorsrepresentanabstractionlyinginbetweenFunctor
andMonadinexpressivity,firstdescribedbyMcBrideandPaterson.Thetitleoftheirclassicpaper,ApplicativeProgrammingwithEffects
(http://www.soi.city.ac.uk/~ross/papers/Applicative.html),givesahintattheintendedintuitionbehindtheApplicative
(http://www.haskell.org/ghc/docs/latest/html/libraries/base/ControlApplicative.html)typeclass.Itencapsulatescertainsortsofeffectful
computationsinafunctionallypureway,andencouragesanapplicativeprogrammingstyle.Exactlywhatthesethingsmeanwillbeseenlater.

4.1Definition
RecallthatFunctorallowsustoliftanormalfunctiontoafunctiononcomputationalcontexts.Butfmapdoesntallowustoapplyafunction
whichisitselfinacontexttoavalueinacontext.Applicativegivesusjustsuchatool,(<*>).Italsoprovidesamethod,pure,forembedding
valuesinadefault,effectfreecontext.HereisthetypeclassdeclarationforApplicative,asdefinedinControl.Applicative:
classFunctorf=>Applicativefwhere
pure::a>fa
(<*>)::f(a>b)>fa>fb

NotethateveryApplicativemustalsobeaFunctor.Infact,aswewillsee,fmapcanbeimplementedusingtheApplicativemethods,soevery
ApplicativeisafunctorwhetherwelikeitornottheFunctorconstraintforcesustobehonest.
Asalways,itscrucialtounderstandthetypesignatures.First,consider(<*>):thebestwayofthinkingaboutit
comesfromnotingthatthetypeof(<*>)issimilartothetypeof($) ,butwitheverythingenclosedinanf.In
otherwords,(<*>)isjustfunctionapplicationwithinacomputationalcontext.Thetypeof(<*>)isalsovery
similartothetypeoffmaptheonlydifferenceisthatthefirstparameterisf(a>b),afunctioninacontext,
insteadofanormalfunction(a>b).

Recallthat($)isjust
functionapplication:f$x=
fx.

puretakesavalueofanytypea,andreturnsacontext/containeroftypefa.Theintentionisthatpurecreatessomesortofdefaultcontaineror

effectfreecontext.Infact,thebehaviorofpureisquiteconstrainedbythelawsitshouldsatisfyinconjunctionwith(<*>).Usually,foragiven
implementationof(<*>)thereisonlyonepossibleimplementationofpure.
(NotethatpreviousversionsoftheTypeclassopediaexplainedpureintermsofatypeclassPointed,whichcanstillbefoundinthepointed
package(http://hackage.haskell.org/package/pointed).However,thecurrentconsensusisthatPointedisnotveryusefulafterall.Foramore
detailedexplanation,seeWhynotPointed?)

4.2Laws
Traditionally,therearefourlawsthatApplicativeinstancesshouldsatisfy .Insomesense,theyareall
concernedwithmakingsurethatpuredeservesitsname:
Theidentitylaw:
pureid<*>v=v

Homomorphism:

puref<*>purex=pure(fx)

Intuitively,applyinganoneffectfulfunctiontoanoneffectfulargumentinaneffectfulcontextisthe
sameasjustapplyingthefunctiontotheargumentandtheninjectingtheresultintothecontextwithpure.
Interchange:

Seehaddockfor
Applicative
(http://www.haskell.org/ghc/docs/latest/
Applicative.html)and
Applicativeprogramming
witheffects
(http://www.soi.city.ac.uk/~ross/papers/

u<*>purey=pure($y)<*>u

Intuitively,thissaysthatwhenevaluatingtheapplicationofaneffectfulfunctiontoapureargument,theorderinwhichweevaluatethe
functionanditsargumentdoesn'tmatter.
Composition:
u<*>(v<*>w)=pure(.)<*>u<*>v<*>w

Thisoneisthetrickiestlawtogainintuitionfor.Insomesenseitisexpressingasortofassociativitypropertyof(<*>).Thereadermaywish
tosimplyconvincethemselvesthatthislawistypecorrect.
Consideredaslefttorightrewriterules,thehomomorphism,interchange,andcompositionlawsactuallyconstituteanalgorithmfortransforming
anyexpressionusingpureand(<*>)intoacanonicalformwithonlyasingleuseofpureattheverybeginningandonlyleftnestedoccurrencesof
(<*>).Compositionallowsreassociating(<*>)interchangeallowsmovingoccurrencesofpureleftwardsandhomomorphismallowscollapsing
multipleadjacentoccurrencesofpureintoone.

ThereisalsoalawspecifyinghowApplicativeshouldrelatetoFunctor:
fmapgx=pureg<*>x

Itsaysthatmappingapurefunctiongoveracontextxisthesameasfirstinjectinggintoacontextwithpure,andthenapplyingittoxwith(<*>).
Inotherwords,wecandecomposefmapintotwomoreatomicoperations:injectionintoacontext,andapplicationwithinacontext.The
Control.Applicativemodulealsodefines(<$>)asasynonymforfmap,sotheabovelawcanalsobeexpressedas:
g<$>x=pureg<*>x.

Exercises
1. (Tricky)Onemightimagineavariantoftheinterchangelawthat
sayssomethingaboutapplyingapurefunctiontoaneffectful
argument.Usingtheabovelaws,provethat
puref<*>x=pure(flip($))<*>x<*>puref

4.3Instances
MostofthestandardtypeswhichareinstancesofFunctorarealsoinstancesofApplicative.
MaybecaneasilybemadeaninstanceofApplicativewritingsuchaninstanceisleftasanexerciseforthereader.

Thelisttypeconstructor[]canactuallybemadeaninstanceofApplicativeintwowaysessentially,itcomesdowntowhetherwewanttothinkof
listsasorderedcollectionsofelements,orascontextsrepresentingmultipleresultsofanondeterministiccomputation(seeWadlersHowtoreplace
failurebyalistofsuccesses(http://www.springerlink.com/content/y7450255v2670167/)).
Letsfirstconsiderthecollectionpointofview.Sincetherecanonlybeoneinstanceofagiventypeclassforanyparticulartype,oneorbothofthe
listinstancesofApplicativeneedtobedefinedforanewtypewrapperasithappens,thenondeterministiccomputationinstanceisthedefault,and
thecollectioninstanceisdefinedintermsofanewtypecalledZipList.Thisinstanceis:
newtypeZipLista=ZipList{getZipList::[a]}

instanceApplicativeZipListwhere
pure=undefinedexercise
(ZipListgs)<*>(ZipListxs)=ZipList(zipWith($)gsxs)

Toapplyalistoffunctionstoalistofinputswith(<*>),wejustmatchupthefunctionsandinputselementwise,andproducealistoftheresulting
outputs.Inotherwords,weziptheliststogetherwithfunctionapplication,($)hencethenameZipList.
TheotherApplicativeinstanceforlists,basedonthenondeterministiccomputationpointofview,is:
instanceApplicative[]where
purex=[x]
gs<*>xs=[gx|g<gs,x<xs]

Insteadofapplyingfunctionstoinputspairwise,weapplyeachfunctiontoalltheinputsinturn,andcollectalltheresultsinalist.
Nowwecanwritenondeterministiccomputationsinanaturalstyle.Toaddthenumbers3and4deterministically,wecanofcoursewrite(+)34.
Butsupposeinsteadof3wehaveanondeterministiccomputationthatmightresultin2,3,or4thenwecanwrite
pure(+)<*>[2,3,4]<*>pure4

or,moreidiomatically,
(+)<$>[2,3,4]<*>pure4.

ThereareseveralotherApplicativeinstancesaswell:
IOisaninstanceofApplicative,andbehavesexactlyasyouwouldthink:toexecutem1<*>m2,firstm1isexecuted,resultinginafunctionf,
thenm2isexecuted,resultinginavaluex,andfinallythevaluefxisreturnedastheresultofexecutingm1<*>m2.
((,)a)isanApplicative,aslongasaisaninstanceofMonoid(sectionMonoid).Theavaluesareaccumulatedinparallelwiththe

computation.
TheApplicativemoduledefinestheConsttypeconstructoravalueoftypeConstabsimplycontainsana.Thisisaninstanceof
ApplicativeforanyMonoidathisinstancebecomesespeciallyusefulinconjunctionwiththingslikeFoldable(sectionFoldable).

TheWrappedMonadandWrappedArrownewtypesmakeanyinstancesofMonad(sectionMonad)orArrow(sectionArrow)respectivelyinto
instancesofApplicativeaswewillseewhenwestudythosetypeclasses,botharestrictlymoreexpressivethanApplicative,inthesense
thattheApplicativemethodscanbeimplementedintermsoftheirmethods.
Exercises
1. ImplementaninstanceofApplicativeforMaybe.
2. DeterminethecorrectdefinitionofpurefortheZipListinstanceof
Applicativethereisonlyoneimplementationthatsatisfiesthe
lawrelatingpureand(<*>).

4.4Intuition
McBrideandPatersonspaperintroducesthenotation
todenotefunctionapplicationinacomputationalcontext.Ifeach
hastype
forsomeapplicativefunctor ,and hastype
,thentheentireexpression
has
type
.Youcanthinkofthisasapplyingafunctiontomultipleeffectfularguments.Inthissense,thedoublebracketnotationisa
generalizationoffmap,whichallowsustoapplyafunctiontoasingleargumentinacontext.
WhydoweneedApplicativetoimplementthisgeneralizationoffmap?Supposeweusefmaptoapplygtothefirstparameterx1.Thenweget
somethingoftypef(t2>...t),butnowwearestuck:wecantapplythisfunctioninacontexttothenextargumentwithfmap.However,this
ispreciselywhat(<*>)allowsustodo.
Thissuggeststhepropertranslationoftheidealizednotation

intoHaskell,namely

g<$>x1<*>x2<*>...<*>xn,

recallingthatControl.Applicativedefines(<$>)asconvenientinfixshorthandforfmap.Thisiswhatismeantbyanapplicativestyleeffectful
computationscanstillbedescribedintermsoffunctionapplicationtheonlydifferenceisthatwehavetousethespecialoperator(<*>)for
applicationinsteadofsimplejuxtaposition.
Notethatpureallowsembeddingnoneffectfulargumentsinthemiddleofanidiomaticapplication,like
g<$>x1<*>purex2<*>x3

whichhastypefd,given
g::a>b>c>d
x1::fa
x2::b
x3::fc

Thedoublebracketsarecommonlyknownasidiombrackets,becausetheyallowwritingidiomaticfunctionapplication,thatis,function
applicationthatlooksnormalbuthassomespecial,nonstandardmeaning(determinedbytheparticularinstanceofApplicativebeingused).Idiom
bracketsarenotsupportedbyGHC,buttheyaresupportedbytheStrathclydeHaskellEnhancement
(http://personal.cis.strath.ac.uk/~conor/pub/she/),apreprocessorwhich(amongmanyotherthings)translatesidiombracketsintostandardusesof
(<$>)and(<*>).ThiscanresultinmuchmorereadablecodewhenmakingheavyuseofApplicative.

4.5Alternativeformulation
Analternative,equivalentformulationofApplicativeisgivenby
classFunctorf=>Monoidalfwhere
unit::f()
(**)::fa>fb>f(a,b)

Intuitively,thisstatesthatamonoidalfunctor isonewhichhassomesortof"defaultshape"andwhich
supportssomesortof"combining"operation.pureand(<*>)areequivalentinpowertounitand(**)(seethe
Exercisesbelow).Moretechnically,theideaisthatfpreservesthe"monoidalstructure"givenbythepairing
constructor(,)andunittype().Thiscanbeseenevenmoreclearlyifwerewritethetypesofunitand(**)as
unit'::()>f()
(**')::(fa,fb)>f(a,b)

Furthermore,todeservethename"monoidal"(seethesectiononMonoids),instancesofMonoidaloughtto
satisfythefollowinglaws,whichseemmuchmorestraightforwardthanthetraditionalApplicativelaws:

Incategorytheoryspeak,
wesayfisalaxmonoidal
functorbecausetherearen't
necessarilyfunctionsinthe
otherdirection,likef(a,b)
>(fa,fb).

Leftidentity :

Inthisandthefollowing
laws,referstoisomorphism
ratherthanequality.In
particularweconsider(x,())
x((),x)and((x,y),z)
(x,(y,z)).

unit**vv

Rightidentity:

u**unitu

Associativity:

u**(v**w)(u**v)**w

TheseturnouttobeequivalenttotheusualApplicativelaws.Inacategorytheorysetting,onewouldalso
requireanaturalitylaw:
Naturality:

Hereg***h=\(x,y)>
(gx,hy).SeeArrows.

fmap(g***h)(u**v)=fmapgu**fmaphv

butinthecontextofHaskell,thisisafreetheorem.
MuchofthissectionwastakenfromablogpostbyEdwardZ.Yang(http://blog.ezyang.com/2012/08/applicativefunctors/)seehisactualpostfor
abitmoreinformation.
Exercises
1. Implementpureand(<*>)intermsofunitand(**),andvice
versa.
2. ArethereanyApplicativeinstancesforwhichtherearealso
functionsf()>()andf(a,b)>(fa,fb),satisfyingsome
"reasonable"laws?
3. (Tricky)Provethatgivenyourimplementationsfromtheprevious
exercise,theusualApplicativelawsandtheMonoidallawsstated
aboveareequivalent.

4.6Furtherreading
Therearemanyotherusefulcombinatorsinthestandardlibrariesimplementedintermsofpureand(<*>):forexample,(*>),(<*),(<**>),(<$),
andsoon(seehaddockforApplicative(http://www.haskell.org/ghc/docs/latest/html/libraries/base4.7.0.0/ControlApplicative.html)).Judicious
useofsuchsecondarycombinatorscanoftenmakecodeusingApplicativesmucheasiertoread.
McBrideandPatersonsoriginalpaper(http://www.soi.city.ac.uk/~ross/papers/Applicative.html)isatreasuretroveofinformationandexamples,
aswellassomeperspectivesontheconnectionbetweenApplicativeandcategorytheory.Beginnerswillfinditdifficulttomakeitthroughthe
entirepaper,butitisextremelywellmotivatedevenbeginnerswillbeabletogleansomethingfromreadingasfarastheyareable.
ConalElliotthasbeenoneofthebiggestproponentsofApplicative.Forexample,thePanlibraryforfunctional
images(http://conal.net/papers/functionalimages/)andthereactivelibraryforfunctionalreactiveprogramming
(FRP) makekeyuseofithisblogalsocontainsmanyexamplesofApplicativeinaction
(http://conal.net/blog/tag/applicativefunctor).BuildingontheworkofMcBrideandPaterson,Elliottalsobuilt
theTypeComposelibrary,whichembodiestheobservation(amongothers)thatApplicativetypesareclosed
undercompositiontherefore,Applicativeinstancescanoftenbeautomaticallyderivedforcomplextypesbuilt
outofsimplerones.

Introducedbyanearlier
paper
(http://conal.net/papers/simply
reactive/)thatwassince
supersededbyPushpull
functionalreactive
programming
(http://conal.net/papers/push
pullfrp/).

AlthoughtheParsecparsinglibrary(http://hackage.haskell.org/package/parsec)(paper
(http://legacy.cs.uu.nl/daan/download/papers/parsecpaper.pdf))wasoriginallydesignedforuseasamonad,in
itsmostcommonusecasesanApplicativeinstancecanbeusedtogreateffectBryanOSullivansblogpost
(http://www.serpentine.com/blog/2008/02/06/thebasicsofapplicativefunctorsputtopracticalwork/)isagoodstartingpoint.Iftheextrapower
providedbyMonadisntneeded,itsusuallyagoodideatouseApplicativeinstead.
AcoupleotherniceexamplesofApplicativeinactionincludetheConfigFileandHSQLlibraries
(http://web.archive.org/web/20090416111947/chrisdone.com/blog/html/20090210applicativeconfigfilehsql.html)andtheformletslibrary
(http://groups.inf.ed.ac.uk/links/formlets/).
GershomBazerman'spost(http://comonad.com/reader/2012/abstractingwithapplicatives/)containsmanyinsightsintoapplicatives.

5Monad
Itsasafebetthatifyourereadingthis,youveheardofmonadsalthoughitsquitepossibleyouveneverheardofApplicativebefore,orArrow,
orevenMonoid.WhyaremonadssuchabigdealinHaskell?Thereareseveralreasons.

Haskelldoes,infact,singleoutmonadsforspecialattentionbymakingthemtheframeworkinwhichtoconstructI/Ooperations.
Haskellalsosinglesoutmonadsforspecialattentionbyprovidingaspecialsyntacticsugarformonadicexpressions:thedonotation.
MonadhasbeenaroundlongerthanotherabstractmodelsofcomputationsuchasApplicativeorArrow.
Themoremonadtutorialsthereare,theharderpeoplethinkmonadsmustbe,andthemorenewmonadtutorialsarewrittenbypeoplewho
thinktheyfinallygetmonads(themonadtutorialfallacy(http://byorgey.wordpress.com/2009/01/12/abstractionintuitionandthemonad
tutorialfallacy/)).
Iwillletyoujudgeforyourselfwhetherthesearegoodreasons.
Intheend,despiteallthehoopla,Monadisjustanothertypeclass.Letstakealookatitsdefinition.

5.1Definition
ThetypeclassdeclarationforMonad(http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Monad)is:
classMonadmwhere
return::a>ma
(>>=)::ma>(a>mb)>mb
(>>)::ma>mb>mb
m>>n=m>>=\_>n

fail::String>ma

TheMonadtypeclassisexportedbythePrelude,alongwithafewstandardinstances.However,manyutilityfunctionsarefoundinControl.Monad
(http://www.haskell.org/ghc/docs/latest/html/libraries/base/ControlMonad.html),andtherearealsoseveralinstances(suchas((>)e))definedin
Control.Monad.Instances(http://www.haskell.org/ghc/docs/latest/html/libraries/base/ControlMonadInstances.html).
LetsexaminethemethodsintheMonadclassonebyone.Thetypeofreturnshouldlookfamiliaritsthesame
aspure.Indeed,returnispure,butwithanunfortunatename.(Unfortunate,sincesomeonecomingfroman
imperativeprogrammingbackgroundmightthinkthatreturnisliketheCorJavakeywordofthesamename,
wheninfactthesimilaritiesareminimal.)Fromamathematicalpointofview,everymonadisanapplicative
functor,butforhistoricalreasons,theMonadtypeclassdeclarationunfortunatelydoesnotrequirethis.

However,asofGHC7.10
thiswillbefixed!

Wecanseethat(>>)isaspecializedversionof(>>=),withadefaultimplementationgiven.Itisonlyincludedinthetypeclassdeclarationsothat
specificinstancesofMonadcanoverridethedefaultimplementationof(>>)withamoreefficientone,ifdesired.Also,notethatalthough_>>n=
nwouldbeatypecorrectimplementationof(>>),itwouldnotcorrespondtotheintendedsemantics:theintentionisthatm>>nignorestheresult
ofm,butnotitseffects.
ThefailfunctionisanawfulhackthathasnoplaceintheMonadclassmoreonthislater.
TheonlyreallyinterestingthingtolookatandwhatmakesMonadstrictlymorepowerfulthanApplicativeis(>>=),whichisoftencalledbind.
AnalternativedefinitionofMonadcouldlooklike:
classApplicativem=>Monad'mwhere
(>>=)::ma>(a>mb)>mb

Wecouldspendawhiletalkingabouttheintuitionbehind(>>=)andwewill.Butfirst,letslookatsomeexamples.

5.2Instances
EvenifyoudontunderstandtheintuitionbehindtheMonadclass,youcanstillcreateinstancesofitbyjustseeingwherethetypesleadyou.You
maybesurprisedtofindthatthisactuallygetsyoualongwaytowardsunderstandingtheintuitionattheveryleast,itwillgiveyousomeconcrete
examplestoplaywithasyoureadmoreabouttheMonadclassingeneral.ThefirstfewexamplesarefromthestandardPreludetheremaining
examplesarefromthetransformerspackage(http://hackage.haskell.org/package/transformers).
ThesimplestpossibleinstanceofMonadisIdentity(http://hackage.haskell.org/packages/archive/mtl/1.1.0.2/doc/html/ControlMonad
Identity.html),whichisdescribedinDanPiponishighlyrecommendedblogpostonTheTrivialMonad
(http://blog.sigfpe.com/2007/04/trivialmonad.html).Despitebeingtrivial,itisagreatintroductiontotheMonadtypeclass,andcontains
somegoodexercisestogetyourbrainworking.
ThenextsimplestinstanceofMonadisMaybe.Wealreadyknowhowtowritereturn/pureforMaybe.Sohowdowewrite(>>=)?Well,lets
thinkaboutitstype.SpecializingforMaybe,wehave
(>>=)::Maybea>(a>Maybeb)>Maybeb.

Ifthefirstargumentto(>>=)isJustx,thenwehavesomethingoftypea(namely,x),towhichwecanapplythesecondargumentresulting
inaMaybeb,whichisexactlywhatwewanted.Whatifthefirstargumentto(>>=)isNothing?Inthatcase,wedonthaveanythingtowhich
wecanapplythea>Maybebfunction,sotheresonlyonethingwecando:yieldNothing.Thisinstanceis:
instanceMonadMaybewhere
return=Just

(Justx)>>=g=gx
Nothing>>=_=Nothing

Wecanalreadygetabitofintuitionastowhatisgoingonhere:ifwebuildupacomputationbychainingtogetherabunchoffunctionswith
(>>=),assoonasanyoneofthemfails,theentirecomputationwillfail(becauseNothing>>=fisNothing,nomatterwhatfis).Theentire
computationsucceedsonlyifalltheconstituentfunctionsindividuallysucceed.SotheMaybemonadmodelscomputationswhichmayfail.
TheMonadinstanceforthelistconstructor[]issimilartoitsApplicativeinstanceseetheexercisebelow.
Ofcourse,theIOconstructorisfamouslyaMonad,butitsimplementationissomewhatmagical,andmayinfactdifferfromcompilerto
compiler.ItisworthemphasizingthattheIOmonadistheonlymonadwhichismagical.Itallowsustobuildup,inanentirelypureway,
valuesrepresentingpossiblyeffectfulcomputations.Thespecialvaluemain,oftypeIO(),istakenbytheruntimeandactuallyexecuted,
producingactualeffects.Everyothermonadisfunctionallypure,andrequiresnospecialcompilersupport.Weoftenspeakofmonadic
valuesaseffectfulcomputations,butthisisbecausesomemonadsallowustowritecodeasifithassideeffects,wheninfactthemonadis
hidingtheplumbingwhichallowstheseapparentsideeffectstobeimplementedinafunctionallypureway.
Asmentionedearlier,((>)e)isknownasthereadermonad,sinceitdescribescomputationsinwhichavalueoftypeeisavailableasa
readonlyenvironment.TheControl.Monad.Reader(http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/ControlMonad
Reader.html)moduleprovidestheReadereatype,whichisjustaconvenientnewtypewrapperaround(e>a),alongwithanappropriate
MonadinstanceandsomeReaderspecificutilityfunctionssuchasask(retrievetheenvironment),asks(retrieveafunctionofthe
environment),andlocal(runasubcomputationunderadifferentenvironment).
TheControl.Monad.Writer(http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/ControlMonadWriterLazy.html)module
providestheWritermonad,whichallowsinformationtobecollectedasacomputationprogresses.Writerwaisisomorphicto(a,w),where
theoutputvalueaiscarriedalongwithanannotationorlogoftypew,whichmustbeaninstanceofMonoid(seesectionMonoid)the
specialfunctiontellperformslogging.
TheControl.Monad.State(http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/ControlMonadStateLazy.html)moduleprovides
theStatesatype,anewtypewrapperarounds>(a,s).SomethingoftypeStatesarepresentsastatefulcomputationwhichproducesan
abutcanaccessandmodifythestateoftypesalongtheway.ThemodulealsoprovidesStatespecificutilityfunctionssuchasget(readthe
currentstate),gets(readafunctionofthecurrentstate),put(overwritethestate),andmodify(applyafunctiontothestate).
TheControl.Monad.Cont(http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/ControlMonadCont.html)moduleprovidesthe
Contmonad,whichrepresentscomputationsincontinuationpassingstyle.Itcanbeusedtosuspendandresumecomputations,andto
implementnonlocaltransfersofcontrol,coroutines,othercomplexcontrolstructuresallinafunctionallypureway.Conthasbeencalled
themotherofallmonads(http://blog.sigfpe.com/2008/12/motherofallmonads.html)becauseofitsuniversalproperties.
Exercises
1. ImplementaMonadinstanceforthelistconstructor,[].Followthe
types!
2. ImplementaMonadinstancefor((>)e).
3. ImplementFunctorandMonadinstancesforFreef,definedas
dataFreefa=Vara
|Node(f(Freefa))

YoumayassumethatfhasaFunctorinstance.Thisisknownasthe
freemonadbuiltfromthefunctorf.

5.3Intuition
Letslookmorecloselyatthetypeof(>>=).Thebasicintuitionisthatitcombinestwocomputationsintoonelargercomputation.Thefirst
argument,ma,isthefirstcomputation.However,itwouldbeboringifthesecondargumentwerejustanmbthentherewouldbenowayforthe
computationstointeractwithoneanother(actually,thisisexactlythesituationwithApplicative).So,thesecondargumentto(>>=)hastypea>
mb:afunctionofthistype,givenaresultofthefirstcomputation,canproduceasecondcomputationtoberun.Inotherwords,x>>=kisa
computationwhichrunsx,andthenusestheresult(s)ofxtodecidewhatcomputationtorunsecond,usingtheoutputofthesecondcomputationas
theresultoftheentirecomputation.
Intuitively,itisthisabilitytousetheoutputfrompreviouscomputationstodecidewhatcomputationstorun
nextthatmakesMonadmorepowerfulthanApplicative.ThestructureofanApplicativecomputationisfixed,
whereasthestructureofaMonadcomputationcanchangebasedonintermediateresults.Thisalsomeansthat
parsersbuiltusinganApplicativeinterfacecanonlyparsecontextfreelanguagesinordertoparsecontext
sensitivelanguagesaMonadinterfaceisneeded.
ToseetheincreasedpowerofMonadfromadifferentpointofview,letsseewhathappensifwetryto
implement(>>=)intermsoffmap,pure,and(<*>).Wearegivenavaluexoftypema,andafunctionkoftypea
>mb,sotheonlythingwecandoisapplyktox.Wecantapplyitdirectly,ofcoursewehavetousefmapto
liftitoverthem.Butwhatisthetypeoffmapk?Well,itsma>m(mb).Soafterweapplyittox,weareleft
withsomethingoftypem(mb)butnowwearestuckwhatwereallywantisanmb,buttheresnowaytoget
therefromhere.Wecanaddmsusingpure,butwehavenowaytocollapsemultiplemsintoone.

Actually,becauseHaskell
allowsgeneralrecursion,this
isalie:usingaHaskell
parsinglibraryonecan
recursivelyconstructinfinite
grammars,andhence
Applicative(togetherwith
Alternative)isenoughto
parseanycontextsensitive
languagewithafinite
alphabet.SeeParsing
contextsensitivelanguages

Thisabilitytocollapsemultiplemsisexactlytheabilityprovidedbythefunctionjoin::m(ma)>ma,and
itshouldcomeasnosurprisethatanalternativedefinitionofMonadcanbegivenintermsofjoin:
classApplicativem=>Monad''mwhere
join::m(ma)>ma

Infact,thecanonicaldefinitionofmonadsincategorytheoryisintermsofreturn,fmap,andjoin(oftencalled
,T,andinthemathematicalliterature).Haskellusesanalternativeformulationwith(>>=)insteadofjoin
sinceitismoreconvenienttouse .However,sometimesitcanbeeasiertothinkaboutMonadinstancesin
termsofjoin,sinceitisamoreatomicoperation.(Forexample,joinforthelistmonadisjustconcat.)
Exercises
1. Implement(>>=)intermsoffmap(orliftM)andjoin.
2. Nowimplementjoinandfmap(liftM)intermsof(>>=)and
return.

withApplicative
(http://byorgey.wordpress.com/2012/01
contextsensitivelanguages
withapplicative/).
Youmighthearsome
peopleclaimthatthatthe
definitionintermsofreturn,
fmap,andjoinisthemath
definitionandthedefinition
intermsofreturnand(>>=)
issomethingspecificto
Haskell.Infact,both
definitionswereknowninthe
mathematicscommunitylong
beforeHaskellpickedup
monads.

5.4Utilityfunctions
TheControl.Monad(http://www.haskell.org/ghc/docs/latest/html/libraries/base/ControlMonad.html)moduleprovidesalargenumberofconvenient
utilityfunctions,allofwhichcanbeimplementedintermsofthebasicMonadoperations(returnand(>>=)inparticular).Wehavealreadyseenone
ofthem,namely,join.Wealsomentionsomeothernoteworthyoneshereimplementingtheseutilityfunctionsoneselfisagoodexercise.Fora
moredetailedguidetothesefunctions,withcommentaryandexamplecode,seeHenkJanvanTuylstour
(http://members.chello.nl/hjgtuyl/tourdemonad.html).
liftM::Monadm=>(a>b)>ma>mb.Thisshouldbefamiliarofcourse,itisjustfmap.Thefact
thatwehavebothfmapandliftMisanunfortunateconsequenceofthefactthattheMonadtypeclassdoes
notrequireaFunctorinstance,eventhoughmathematicallyspeaking,everymonadisafunctor.However,
fmapandliftMareessentiallyinterchangeable,sinceitisabug(inasocialratherthantechnicalsense)for

anytypetobeaninstanceofMonadwithoutalsobeinganinstanceofFunctor .

Thiswillmostlikely
changeinHaskell2014with
theimplementationofthe
Haskell2014Applicative=>
Monadproposal.

ap::Monadm=>m(a>b)>ma>mbshouldalsobefamiliar:itisequivalentto(<*>),justifying
theclaimthattheMonadinterfaceisstrictlymorepowerfulthanApplicative.WecanmakeanyMonadintoaninstanceofApplicativeby
settingpure=returnand(<*>)=ap.
sequence::Monadm=>[ma]>m[a]takesalistofcomputationsandcombinesthemintoonecomputationwhichcollectsalistoftheir
results.ItisagainsomethingofahistoricalaccidentthatsequencehasaMonadconstraint,sinceitcanactuallybeimplementedonlyinterms
ofApplicative.Thereisanadditionalgeneralizationofsequencetostructuresotherthanlists,whichwillbediscussedinthesectionon
Traversable.
replicateM::Monadm=>Int>ma>m[a]issimplyacombinationofreplicate

(http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:replicate)andsequence.
when::Monadm=>Bool>m()>m()conditionallyexecutesacomputation,evaluatingtoitssecondargumentifthetestisTrue,andto
return()ifthetestisFalse.AcollectionofothersortsofmonadicconditionalscanbefoundintheIfElsepackage

(http://hackage.haskell.org/package/IfElse).
mapM::Monadm=>(a>mb)>[a]>m[b]mapsitsfirstargumentoverthesecond,andsequencestheresults.TheforMfunctionis
justmapMwithitsargumentsreverseditiscalledforMsinceitmodelsgeneralizedforloops:thelist[a]providestheloopindices,andthe
functiona>mbspecifiesthebodyoftheloopforeachindex.
(=<<)::Monadm=>(a>mb)>ma>mbisjust(>>=)withitsargumentsreversedsometimesthisdirectionismoreconvenientsince

itcorrespondsmorecloselytofunctionapplication.
(>=>)::Monadm=>(a>mb)>(b>mc)>a>mcissortoflikefunctioncomposition,butwithanextramontheresulttypeof
eachfunction,andtheargumentsswapped.Wellhavemoretosayaboutthisoperationlater.Thereisalsoaflippedvariant,(<=<).

TheguardfunctionisforusewithinstancesofMonadPlus,whichisdiscussedattheendoftheMonoidsection.
Manyofthesefunctionsalsohaveunderscoredvariants,suchassequence_andmapM_thesevariantsthrowawaytheresultsofthecomputations
passedtothemasarguments,usingthemonlyfortheirsideeffects.
OthermonadicfunctionswhichareoccasionallyusefulincludefilterM,zipWithM,foldM,andforever.

5.5Laws

ThereareseverallawsthatinstancesofMonadshouldsatisfy(seealsotheMonadlawswikipage).Thestandardpresentationis:
returna>>=k=ka
m>>=return=m
m>>=(\x>kx>>=h)=(m>>=k)>>=h

fmapfxs=xs>>=return.f=liftMfxs

Thefirstandsecondlawsexpressthefactthatreturnbehavesnicely:ifweinjectavalueaintoamonadiccontextwithreturn,andthenbindtok,
itisthesameasjustapplyingktoainthefirstplaceifwebindacomputationmtoreturn,nothingchanges.Thethirdlawessentiallysaysthat
(>>=)isassociative,sortof.ThelastlawensuresthatfmapandliftMarethesamefortypeswhichareinstancesofbothFunctorandMonadwhich,
asalreadynoted,shouldbeeveryinstanceofMonad.
However,thepresentationoftheabovelaws,especiallythethird,ismarredbytheasymmetryof(>>=).Itshard
Iliketopronouncethis
tolookatthelawsandseewhattheyrereallysaying.Ipreferamuchmoreelegantversionofthelaws,whichis
operatorfish.
formulatedintermsof(>=>) .Recallthat(>=>)composestwofunctionsoftypea>mbandb>mc.
Youcanthinkofsomethingoftypea>mb(roughly)asafunctionfromatobwhichmayalsohavesomesort
ofeffectinthecontextcorrespondingtom.(>=>)letsuscomposetheseeffectfulfunctions,andwewouldliketoknowwhatproperties(>=>)has.
Themonadlawsreformulatedintermsof(>=>)are:
return>=>g=g
g>=>return=g
(g>=>h)>=>k=g>=>(h>=>k)

Ah,muchbetter!Thelawssimplystatethatreturnistheidentityof(>=>),andthat(>=>)isassociative .
Thereisalsoaformulationofthemonadlawsintermsoffmap,return,andjoinforadiscussionofthis
formulation,seetheHaskellwikibookpageoncategorytheory
(http://en.wikibooks.org/wiki/Haskell/Category_theory).
Exercises
1. Giventhedefinitiong>=>h=\x>gx>>=h,provethe
equivalenceoftheabovelawsandtheusualmonadlaws.

Asfansofcategorytheory
willnote,theselawssay
preciselythatfunctionsof
typea>mbarethearrows
ofacategorywith(>=>)as
composition!Indeed,thisis
knownastheKleislicategory
ofthemonadm.Itwillcome
upagainwhenwediscuss
Arrows.

5.6donotation
Haskellsspecialdonotationsupportsanimperativestyleofprogrammingbyprovidingsyntacticsugarforchainsofmonadicexpressions.The
genesisofthenotationliesinrealizingthatsomethinglikea>>=\x>b>>c>>=\y>dcanbemorereadablywrittenbyputtingsuccessive
computationsonseparatelines:
a>>=\x>
b>>
c>>=\y>
d

Thisemphasizesthattheoverallcomputationconsistsoffourcomputationsa,b,c,andd,andthatxisboundtotheresultofa,andyisboundtothe
resultofc(b,c,anddareallowedtorefertox,anddisallowedtorefertoyaswell).Fromhereitisnothardtoimagineanicernotation:
do{x<a
;b
;y<c
;d
}

(ThecurlybracesandsemicolonsmayoptionallybeomittedtheHaskellparseruseslayouttodeterminewheretheyshouldbeinserted.)This
discussionshouldmakeclearthatdonotationisjustsyntacticsugar.Infact,doblocksarerecursivelytranslatedintomonadoperations(almost)like
this:
doee
do{e;stmts}e>>do{stmts}
do{v<e;stmts}e>>=\v>do{stmts}
do{letdecls;stmts}letdeclsindo{stmts}

Thisisnotquitethewholestory,sincevmightbeapatterninsteadofavariable.Forexample,onecanwrite
do(x:xs)<foo
barx

butwhathappensiffooproducesanemptylist?Well,rememberthatuglyfailfunctionintheMonadtypeclassdeclaration?Thatswhathappens.
Seesection3.14oftheHaskellReport(http://www.haskell.org/onlinereport/exps.html#sect3.14)forthefulldetails.Seealsothediscussionof
MonadPlusandMonadZerointhesectiononothermonoidalclasses.
Afinalnoteonintuition:donotationplaysverystronglytothecomputationalcontextpointofviewratherthanthecontainerpointofview,
sincethebindingnotationx<missuggestiveofextractingasinglexfrommanddoingsomethingwithit.Butmmayrepresentsomesortofa
container,suchasalistoratreethemeaningofx<misentirelydependentontheimplementationof(>>=).Forexample,ifmisalist,x<m
actuallymeansthatxwilltakeoneachvaluefromthelistinturn.

5.7Furtherreading
PhilipWadlerwasthefirsttoproposeusingmonadstostructurefunctionalprograms.Hispaper
(http://homepages.inf.ed.ac.uk/wadler/topics/monads.html)isstillareadableintroductiontothesubject.
Thereare,ofcourse,numerousmonadtutorialsofvaryingquality .
AfewofthebestincludeCaleGibbardsMonadsascontainers
(http://www.haskell.org/haskellwiki/Monads_as_Containers)andMonadsascomputation
(http://www.haskell.org/haskellwiki/Monads_as_computation)JeffNewbernsAllAboutMonads,a
comprehensiveguidewithlotsofexamplesandDanPiponisYouCouldHaveInventedMonads!
(http://blog.sigfpe.com/2006/08/youcouldhaveinventedmonadsand.html),whichfeaturesgreatexercises.If
youjustwanttoknowhowtouseIO,youcouldconsulttheIntroductiontoIO.Eventhisisjustasamplingthe
monadtutorialstimelineisamorecompletelist.(Allthesemonadtutorialshavepromptedparodieslikethinkof
amonad...(http://koweycode.blogspot.com/2007/01/thinkofmonad.html)aswellasotherkindsofbacklash
likeMonads!(andWhyMonadTutorialsAreAllAwful)
(http://ahamsandwich.wordpress.com/2007/07/26/monadsandwhymonadtutorialsareallawful/)or
Abstraction,intuition,andthemonadtutorialfallacy(http://byorgey.wordpress.com/2009/01/12/abstraction
intuitionandthemonadtutorialfallacy/).)
OthergoodmonadreferenceswhicharenotnecessarilytutorialsincludeHenkJanvanTuylstour
(http://members.chello.nl/hjgtuyl/tourdemonad.html)ofthefunctionsinControl.Monad,DanPiponisfieldguide
(http://blog.sigfpe.com/2006/10/monadsfieldguide.html),TimNewshamsWhatsaMonad?
(http://www.thenewsh.com/~newsham/haskell/monad.html),andChrisSmith'sexcellentarticleWhyDo
MonadsMatter?(http://cdsmith.wordpress.com/2012/04/18/whydomonadsmatter/).Therearealsomanyblog
postswhichhavebeenwrittenonvariousaspectsofmonadsacollectionoflinkscanbefoundunderBlog
articles/Monads.
Forhelpconstructingmonadsfromscratch,andforobtaininga"deepembedding"ofmonadoperationssuitable
forusein,say,compilingadomainspecificlanguage,seeApfelmus'soperationalpackage
(http://projects.haskell.org/operational).
OneofthequirksoftheMonadclassandtheHaskelltypesystemisthatitisnotpossibletostraightforwardly
declareMonadinstancesfortypeswhichrequireaclassconstraintontheirdata,eveniftheyaremonadsfroma
mathematicalpointofview.Forexample,Data.SetrequiresanOrdconstraintonitsdata,soitcannotbeeasily
madeaninstanceofMonad.AsolutiontothisproblemwasfirstdescribedbyEricKidd
(http://www.randomhacks.net/articles/2007/03/15/datasetmonadhaskellmacros),andlatermadeintoalibrary
namedrmonad(http://hackage.haskell.org/cgibin/hackagescripts/package/rmonad)byGaneshSittampalamand
PeterGavin.

AllAboutMonads,
Monadsascontainers
(http://www.haskell.org/haskellwiki/Mo
,Understandingmonads
(http://en.wikibooks.org/w/index.php?
title=Haskell/Understanding_monads)
,TheMonadicWay,You
CouldHaveInvented
Monads!(AndMaybeYou
AlreadyHave.)
(http://blog.sigfpe.com/2006/08/you
couldhaveinventedmonads
and.html),theresamonster
inmyHaskell!
(http://www.haskell.org/pipermail/haske
cafe/2006
November/019190.html),
UnderstandingMonads.For
real.
(http://kawagner.blogspot.com/2007/02/
monadsforreal.html),
Monadsin15minutes:
BacktrackingandMaybe
(http://www.randomhacks.net/articles/2
in15minutes),Monadsas
computation
(http://www.haskell.org/haskellwiki/Mo
,PracticalMonads
(http://metafoo.co.uk/practical
monads.txt)

Therearemanygoodreasonsforeschewingdonotationsomehavegonesofarastoconsideritharmful.
Monadscanbegeneralizedinvariouswaysforanexpositionofonepossibility,seeRobertAtkeyspaperonparameterizedmonads
(http://homepages.inf.ed.ac.uk/ratkey/paramnotionsjfp.pdf),orDanPiponisBeyondMonads(http://blog.sigfpe.com/2009/02/beyond
monads.html).
Forthecategoricallyinclined,monadscanbeviewedasmonoids(FromMonoidstoMonads(http://blog.sigfpe.com/2008/11/frommonoidsto
monads.html))andalsoasclosureoperatorsTriplesandClosure(http://blog.plover.com/math/monadclosure.html).DerekElkinssarticleinissue
13oftheMonad.Reader(http://www.haskell.org/wikiupload/8/85/TMRIssue13.pdf)containsanexpositionofthecategorytheoretic
underpinningsofsomeofthestandardMonadinstances,suchasStateandCont.JonathanHillandKeithClarkehaveanearlypaperexplainingthe
connectionbetweenmonadsastheyariseincategorytheoryandasusedinfunctionalprogramming(http://citeseerx.ist.psu.edu/viewdoc/summary?
doi=10.1.1.53.6497).ThereisalsoawebpagebyOlegKiselyov(http://okmij.org/ftp/Computation/IOmonadhistory.html)explainingthehistory
oftheIOmonad.
LinkstomanymoreresearchpapersrelatedtomonadscanbefoundunderResearchpapers/Monadsandarrows.

6Monadtransformers
Onewouldoftenliketobeabletocombinetwomonadsintoone:forexample,tohavestateful,nondeterministiccomputations(State+[]),or
computationswhichmayfailandcanconsultareadonlyenvironment(Maybe+Reader),andsoon.Unfortunately,monadsdonotcomposeas
nicelyasapplicativefunctors(yetanotherreasontouseApplicativeifyoudontneedthefullpowerthatMonadprovides),butsomemonadscanbe
combinedincertainways.

6.1Standardmonadtransformers
Thetransformers(http://hackage.haskell.org/package/transformers)libraryprovidesanumberofstandardmonadtransformers.Eachmonad
transformeraddsaparticularcapability/feature/effecttoanyexistingmonad.
IdentityT(http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/ControlMonadTransIdentity.html)istheidentity

transformer,whichmapsamonadto(somethingisomorphicto)itself.Thismayseemuselessatfirstglance,butitisusefulforthesame
reasonthattheidfunctionisusefulitcanbepassedasanargumenttothingswhichareparameterizedoveranarbitrarymonad
transformer,whenyoudonotactuallywantanyextracapabilities.
StateT(http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/ControlMonadTransState.html)addsareadwritestate.
ReaderT(http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/ControlMonadTransReader.html)addsareadonly
environment.
WriterT(http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/ControlMonadTransWriter.html)addsawriteonlylog.
RWST(http://hackage.haskell.org/packages/archive/transformers/0.2.2.0/doc/html/ControlMonadTransRWS.html)convenientlycombines
ReaderT,WriterT,andStateTintoone.
MaybeT(http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/ControlMonadTransMaybe.html)addsthepossibilityof
failure.
ErrorT(http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/ControlMonadTransError.html)addsthepossibilityof
failurewithanarbitrarytypetorepresenterrors.
ListT(http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/ControlMonadTransList.html)addsnondeterminism
(however,seethediscussionofListTbelow).
ContT(http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/ControlMonadTransCont.html)addscontinuation
handling.
Forexample,StateTsMaybeisaninstanceofMonadcomputationsoftypeStateTsMaybeamayfail,andhaveaccesstoamutablestateoftypes.
Monadtransformerscanbemultiplystacked.Onethingtokeepinmindwhileusingmonadtransformersisthattheorderofcompositionmatters.
Forexample,whenaStateTsMaybeacomputationfails,thestateceasesbeingupdated(indeed,itsimplydisappears)ontheotherhand,thestate
ofaMaybeT(States)acomputationmaycontinuetobemodifiedevenafterthecomputationhas"failed".Thismayseembackwards,butitis
correct.MonadtransformersbuildcompositemonadsinsideoutMaybeT(States)aisisomorphictos>(Maybea,s).(Lambdabothasan
indispensable@unmtlcommandwhichyoucanusetounpackamonadtransformerstackinthisway.)Intuitively,themonadsbecome"more
fundamental"thefurtherinsidethestackyouget,andtheeffectsofinnermonads"haveprecedence"overtheeffectsofouterones.Ofcourse,this
isjusthandwaving,andifyouareunsureoftheproperorderforsomemonadsyouwishtocombine,thereisnosubstituteforusing@unmtlor
simplytryingoutthevariousoptions.

6.2Definitionandlaws
AllmonadtransformersshouldimplementtheMonadTranstypeclass,definedinControl.Monad.Trans.Class:
classMonadTranstwhere
lift::Monadm=>ma>tma

Itallowsarbitrarycomputationsinthebasemonadmtobeliftedintocomputationsinthetransformedmonadtm.(Notethattypeapplication
associatestotheleft,justlikefunctionapplication,sotma=(tm)a.)
liftmustsatisfythelaws
lift.return=return
lift(m>>=f)=liftm>>=(lift.f)

whichintuitivelystatethatlifttransformsmacomputationsintotmacomputationsina"sensible"way,whichsendsthereturnand(>>=)ofmto
thereturnand(>>=)oftm.
Exercises
1. WhatisthekindoftinthedeclarationofMonadTrans?

6.3Transformertypeclassesand"capability"style
Therearealsotypeclasses(providedbythemtlpackage(http://hackage.haskell.org/package/mtl))forthe
operationsofeachtransformer.Forexample,theMonadStatetypeclassprovidesthestatespecificmethodsget
andput,allowingyoutoconvenientlyusethesemethodsnotonlywithState,butwithanymonadwhichisan
instanceofMonadStateincludingMaybeT(States),StateTs(ReaderTrIO),andsoon.Similartypeclasses
existforReader,Writer,Cont,IO,andothers .
Thesetypeclassesservetwopurposes.First,theygetridof(mostof)theneedforexplicitlyusinglift,givinga
typedirectedwaytoautomaticallydeterminetherightnumberofcallstolift.Simplywritingputwillbe
automaticallytranslatedintolift.put,lift.lift.put,orsomethingsimilardependingonwhatconcrete
monadstackyouareusing.

Theonlyproblemwiththis
schemeisthequadratic
numberofinstancesrequired
asthenumberofstandard
monadtransformersgrows
butasthecurrentsetof
standardmonadtransformers
seemsadequateformost
commonusecases,thismay
notbethatbigofadeal.

Second,theygiveyoumoreflexibilitytoswitchbetweendifferentconcretemonadstacks.Forexample,ifyou
arewritingastatebasedalgorithm,don'twrite
foo::StateIntChar
foo=modify(*2)>>return'x'

butrather
foo::MonadStateIntm=>mChar
foo=modify(*2)>>return'x'

Now,ifsomewheredownthelineyourealizeyouneedtointroducethepossibilityoffailure,youmightswitchfromStateInttoMaybeT(State
Int).Thetypeofthefirstversionoffoowouldneedtobemodifiedtoreflectthischange,butthesecondversionoffoocanstillbeusedasis.
However,thissortof"capabilitybased"style(e.g.specifyingthatfooworksforanymonadwiththe"statecapability")quicklyrunsintoproblems
whenyoutrytonaivelyscaleitup:forexample,whatifyouneedtomaintaintwoindependentstates?Aframeworkforsolvingthisandrelated
problemsisdescribedbySchrijversandOlivera(Monads,zippersandviews:virtualizingthemonadstack,ICFP2011
(http://users.ugent.be/~tschrijv/Research/papers/icfp2011.pdf))andisimplementedintheMonatronpackage
(http://hackage.haskell.org/package/Monatron).

6.4Composingmonads
Isthecompositionoftwomonadsalwaysamonad?Ashintedpreviously,theanswerisno.
SinceApplicativefunctorsareclosedundercomposition,theproblemmustliewithjoin.Indeed,supposemandnarearbitrarymonadstomakea
monadoutoftheircompositionwewouldneedtobeabletoimplement
join::m(n(m(na)))>m(na)

butitisnotclearhowthiscouldbedoneingeneral.Thejoinmethodformisnohelp,becausethetwooccurrencesofmarenotnexttoeachother
(andlikewiseforn).
However,onesituationinwhichitcanbedoneisifndistributesoverm,thatis,ifthereisafunction
distrib::n(ma)>m(na)

satisfyingcertainlaws.SeeJonesandDuponcheel(ComposingMonads(http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.42.2605))see
alsothesectiononTraversable.
Foramuchmoreindepthdiscussionandanalysisofthefailureofmonadstobeclosedundercomposition,seethisquestiononStackOverflow
(http://stackoverflow.com/questions/13034229/concreteexampleshowingthatmonadsarenotclosedundercompositionwithproo?lq=1).
Exercises
Implementjoin::M(N(M(Na)))>M(Na),givendistrib::
N(Ma)>M(Na)andassumingMandNareinstancesofMonad.

6.5Furtherreading
Muchofthemonadtransformerlibrary(originallymtl(http://hackage.haskell.org/package/mtl),nowsplitbetweenmtlandtransformers
(http://hackage.haskell.org/package/transformers)),includingtheReader,Writer,State,andothermonads,aswellasthemonadtransformer
frameworkitself,wasinspiredbyMarkJonessclassicpaperFunctionalProgrammingwithOverloadingandHigherOrderPolymorphism

(http://web.cecs.pdx.edu/~mpj/pubs/springschool.html).Itsstillverymuchworthareadandhighlyreadableafteralmostfifteenyears.
SeeEdwardKmett'smailinglistmessage(http://article.gmane.org/gmane.comp.lang.haskell.libraries/17139)foradescriptionofthehistoryand
relationshipsamongmonadtransformerpackages(mtl,transformers,monadsfd,monadstf).
Therearetwoexcellentreferencesonmonadtransformers.MartinGrabmllersMonadTransformersStepbyStep
(http://www.grabmueller.de/martin/www/pub/Transformers.en.html)isathoroughdescription,withrunningexamples,ofhowtousemonad
transformerstoelegantlybuildupcomputationswithvariouseffects.CaleGibbardsarticle
(http://cale.yi.org/index.php/How_To_Use_Monad_Transformers)onhowtousemonadtransformersismorepractical,describinghowtostructure
codeusingmonadtransformerstomakewritingitaspainlessaspossible.Anothergoodstartingplaceforlearningaboutmonadtransformersisa
blogpostbyDanPiponi(http://blog.sigfpe.com/2006/05/grokhaskellmonadtransformers.html).
TheListTtransformerfromthetransformerspackagecomeswiththecaveatthatListTmisonlyamonadwhenmiscommutative,thatis,whenma
>>=\a>mb>>=\b>fooisequivalenttomb>>=\b>ma>>=\a>foo(i.e.theorderofm'seffectsdoesnotmatter).Foroneexplanation
why,seeDanPiponi'sblogpost"Whyisn'tListT[]amonad"(http://blog.sigfpe.com/2006/11/whyisntlisttmonad.html).Formoreexamples,as
wellasadesignforaversionofListTwhichdoesnothavethisproblem,seeListTdoneright
(http://www.haskell.org/haskellwiki/ListT_done_right).
Thereisanalternativewaytocomposemonads,usingcoproducts,asdescribedbyLthandGhani(http://citeseerx.ist.psu.edu/viewdoc/summary?
doi=10.1.1.8.3581).Thismethodisinterestingbuthasnot(yet?)seenwidespreaduse.Foramorerecentalternative,seeKiselyovetal'sExtensible
Effects:AnAlternativetoMonadTransformers(http://okmij.org/ftp/Haskell/extensible/exteff.pdf).

7MonadFix
Note:MonadFixisincludedhereforcompleteness(andbecauseitisinteresting)butseemsnottobeusedmuch.Skippingthissectiononafirst
readthroughisperfectlyOK(andperhapsevenrecommended).

7.1mdo/dorecnotation
TheMonadFixclassdescribesmonadswhichsupportthespecialfixpointoperationmfix::(a>ma)>ma,
whichallowstheoutputofmonadiccomputationstobedefinedvia(effectful)recursion.Thisissupportedin
GHC(http://www.haskell.org/ghc/docs/latest/html/users_guide/syntaxextns.html#recursivedonotation)bya
specialrecursivedonotation,enabledbytheXDoRecflag .Withinadoblock,onemayhaveanestedrec
block,likeso:

InGHC7.6,theflaghas
beenchangedto
XRecursiveDo.

do{x<foo
;rec{y<baz
;z<bar
;bob
}
;w<frob
}

Normally(ifwehaddoinplaceofrecintheaboveexample),ywouldbeinscopeinbarandbobbutnotinbaz,andzwouldbeinscopeonlyin
bob.Withtherec,however,yandzarebothinscopeinallthreeofbaz,bar,andbob.Arecblockisanalogoustoaletblocksuchas
let{y=baz
;z=bar
}
inbob

because,inHaskell,everyvariableboundinaletblockisinscopethroughouttheentireblock.(Fromthispointofview,Haskell'snormaldo
blocksareanalogoustoScheme'slet*construct.)
Whatcouldsuchafeaturebeusedfor?OneofthemotivatingexamplesgivenintheoriginalpaperdescribingMonadFix(seebelow)isencoding
circuitdescriptions.Alineinadoblocksuchas
x<gateyz

describesagatewhoseinputwiresarelabeledyandzandwhoseoutputwireislabeledx.Many(most?)usefulcircuits,however,involvesomesort
offeedbackloop,makingthemimpossibletowriteinanormaldoblock(sincesomewirewouldhavetobementionedasaninputbeforebeing
listedasanoutput).Usingarecblocksolvesthisproblem.

7.2Examplesandintuition
Ofcourse,noteverymonadsupportssuchrecursivebinding.However,asmentionedabove,itsufficestohaveanimplementationofmfix::(a>
ma)>ma,satisfyingafewlaws.Let'stryimplementingmfixfortheMaybemonad.Thatis,wewanttoimplementafunction

maybeFix::(a>Maybea)>Maybea

Let'sthinkforamomentabouttheimplementation ofthenonmonadicfix::(a>a)>a:
fixf=f(fixf)

Inspiredbyfix,ourfirstattemptatimplementingmaybeFixmightbesomethinglike
maybeFix::(a>Maybea)>Maybea
maybeFixf=maybeFixf>>=f

Actually,fixis
implementedslightly
differentlyforefficiency
reasonsbutthegiven
definitionisequivalentand
simplerforthepresent
purpose.

Thishastherighttype.However,somethingseemswrong:thereisnothinginparticularhereaboutMaybe
maybeFixactuallyhasthemoregeneraltypeMonadm=>(a>ma)>ma.Butdidn'twejustsaythatnotallmonadssupportmfix?
TheansweristhatalthoughthisimplementationofmaybeFixhastherighttype,itdoesnothavetheintendedsemantics.Ifwethinkabouthow
(>>=)worksfortheMaybemonad(bypatternmatchingonitsfirstargumenttoseewhetheritisNothingorJust)wecanseethatthisdefinitionof
maybeFixiscompletelyuseless:itwilljustrecurseinfinitely,tryingtodecidewhetheritisgoingtoreturnNothingorJust,withouteverevenso
muchasaglanceinthedirectionoff.
ThetrickistosimplyassumethatmaybeFixwillreturnJust,andgetonwithlife!
maybeFix::(a>Maybea)>Maybea
maybeFixf=ma
wherema=f(fromJustma)

ThissaysthattheresultofmaybeFixisma,andassumingthatma=Justx,itisdefined(recursively)tobeequaltofx.
WhyisthisOK?Isn'tfromJustalmostasbadasunsafePerformIO?Well,usually,yes.Thisisjustabouttheonlysituationinwhichitisjustified!
TheinterestingthingtonoteisthatmaybeFixwillnevercrashalthoughitmay,ofcourse,failtoterminate.Theonlywaywecouldgetacrashisif
wetrytoevaluatefromJustmawhenweknowthatma=Nothing.Buthowcouldweknowma=Nothing?Sincemaisdefinedasf(fromJustma),it
mustbethatthisexpressionhasalreadybeenevaluatedtoNothinginwhichcasethereisnoreasonforustobeevaluatingfromJustmainthefirst
place!
Toseethisfromanotherpointofview,wecanconsiderthreepossibilities.First,iffoutputsNothingwithoutlookingatitsargument,thenmaybeFix
fclearlyreturnsNothing.Second,iffalwaysoutputsJustx,wherexdependsonitsargument,thentherecursioncanproceedusefully:fromJust
mawillbeabletoevaluatetox,thusfeedingf'soutputbacktoitasinput.Third,ifftriestouseitsargumenttodecidewhethertooutputJustor
Nothing,thenmaybeFixfwillnotterminate:evaluatingf'sargumentrequiresevaluatingmatoseewhetheritisJust,whichrequiresevaluatingf
(fromJustma),whichrequiresevaluatingma,...andsoon.
TherearealsoinstancesofMonadFixforlists(whichworksanalogouslytotheinstanceforMaybe),forST,andforIO.TheinstanceforIO
(http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/SystemIO.html#fixIO)isparticularlyamusing:itcreatesanew(empty)MVar,
immediatelyreadsitscontentsusingunsafeInterleaveIO(whichdelaystheactualreadinglazilyuntilthevalueisneeded),usesthecontentsofthe
MVartocomputeanewvalue,whichitthenwritesbackintotheMVar.Italmostseems,spookily,thatmfixissendingavaluebackintimetoitself
throughtheMVarthoughofcoursewhatisreallygoingonisthatthereadingisdelayedjustlongenough(viaunsafeInterleaveIO)togetthe
processbootstrapped.
Exercises
ImplementaMonadFixinstancefor[].

7.3GHC7.6changes
GHC7.6reinstatedtheoldmdosyntax,sotheexampleatthestartofthissectioncanbewritten
mdo{x<foo
;y<baz
;z<bar
;bob
;w<frob
}

whichwillbetranslatedintotheoriginalexample(assumingthat,say,barandbobrefertoy.Thedifferenceisthatmdowillanalyzethecodein
ordertofindminimalrecursiveblocks,whichwillbeplacedinrecblocks,whereasrecblocksdesugardirectlyintocallstomfixwithoutany
furtheranalysis.

7.4Furtherreading

Formoreinformation(suchastheprecisedesugaringrulesforrecblocks),seeLeventErkkandJohnLaunchbury's2002Haskellworkshoppaper,
ARecursivedoforHaskell(http://sites.google.com/site/leventerkok/recdo.pdf?attredirects=0),orforfulldetails,LeventErkksthesis,Value
RecursioninMonadicComputations(http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.15.1543&rep=rep1&type=pdf).(Note,while
reading,thatMonadFixusedtobecalledMonadRec.)YoucanalsoreadtheGHCusermanualsectiononrecursivedonotation
(http://www.haskell.org/ghc/docs/latest/html/users_guide/syntaxextns.html#recursivedonotation).

8Semigroup
Asemigroupisaset
is,

togetherwithabinaryoperation whichcombineselementsfrom
,forany
whichareelementsof ).

.The

operatorisrequiredtobeassociative(that

Forexample,thenaturalnumbersunderadditionformasemigroup:thesumofanytwonaturalnumbersisanaturalnumber,and
foranynaturalnumbers , ,and .Theintegersundermultiplicationalsoformasemigroup,asdothe
integers(orrationals,orreals)under
or
,Booleanvaluesunderconjunctionanddisjunction,listsunderconcatenation,functionsfroma
settoitselfundercomposition...Semigroupsshowupallovertheplace,onceyouknowtolookforthem.

8.1Definition
Semigroupsarenot(yet?)definedinthebasepackage,butthesemigroups(http://hackage.haskell.org/package/semigroups)packageprovidesa
standarddefinition.
ThedefinitionoftheSemigrouptypeclass(haddock(http://hackage.haskell.org/packages/archive/semigroups/latest/doc/html/DataSemigroup.html)
)isasfollows:
classSemigroupawhere
(<>)::a>a>a

sconcat::NonEmptya>a
sconcat=sconcat(a:|as)=goaaswhere
gob(c:cs)=b<>goccs
gob[]=b

times1p::Wholen=>n>a>a
times1p=...

Thereallyimportantmethodis(<>),representingtheassociativebinaryoperation.Theothertwomethodshavedefaultimplementationsintermsof
(<>),andareincludedinthetypeclassincasesomeinstancescangivemoreefficientimplementationsthanthedefault.sconcatreducesa
nonemptylistusing(<>)times1pnisequivalentto(butmoreefficientthan)sconcat.replicaten.Seethehaddockdocumentation
(http://hackage.haskell.org/packages/archive/semigroups/latest/doc/html/DataSemigroup.html)formoreinformationonsconcatandtimes1p.

8.2Laws
Theonlylawisthat(<>)mustbeassociative:
(x<>y)<>z=x<>(y<>z)

9Monoid
Manysemigroupshaveaspecialelementeforwhichthebinaryoperation
Suchasemigroupwithidentityelementiscalledamonoid.

istheidentity,thatis,

foreveryelementx.

9.1Definition
ThedefinitionoftheMonoidtypeclass(definedinData.Monoidhaddock(http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data
Monoid.html))is:
classMonoidawhere
mempty::a
mappend::a>a>a

mconcat::[a]>a
mconcat=foldrmappendmempty

Thememptyvaluespecifiestheidentityelementofthemonoid,andmappendisthebinaryoperation.Thedefaultdefinitionformconcatreducesa
listofelementsbycombiningthemallwithmappend,usingarightfold.ItisonlyintheMonoidclasssothatspecificinstanceshavetheoptionof

providinganalternative,moreefficientimplementationusually,youcansafelyignoremconcatwhencreatingaMonoidinstance,sinceitsdefault
definitionwillworkjustfine.
TheMonoidmethodsareratherunfortunatelynamedtheyareinspiredbythelistinstanceofMonoid,whereindeedmempty=[]andmappend=(++),
butthisismisleadingsincemanymonoidshavelittletodowithappending(seetheseCommentsfromOCamlHackerBrianHurt
(http://thread.gmane.org/gmane.comp.lang.haskell.cafe/50590)ontheHaskellcafemailinglist).ThiswasimprovedinGHC7.4,where(<>)was
addedasanaliastomappend.

9.2Laws
Ofcourse,everyMonoidinstanceshouldactuallybeamonoidinthemathematicalsense,whichimpliestheselaws:
mempty`mappend`x=x
x`mappend`mempty=x
(x`mappend`y)`mappend`z=x`mappend`(y`mappend`z)

9.3Instances
TherearequiteafewinterestingMonoidinstancesdefinedinData.Monoid.
[a]isaMonoid,withmempty=[]andmappend=(++).Itisnothardtocheckthat(x++y)++z=x++(y++z)foranylistsx,y,andz,
andthattheemptylististheidentity:[]++x=x++[]=x.

Asnotedpreviously,wecanmakeamonoidoutofanynumerictypeundereitheradditionormultiplication.However,sincewecanthave
twoinstancesforthesametype,Data.Monoidprovidestwonewtypewrappers,SumandProduct,withappropriateMonoidinstances.
>getSum(mconcat.mapSum$[1..5])
15
>getProduct(mconcat.mapProduct$[1..5])
120

Thisexamplecodeissilly,ofcoursewecouldjustwrite
sum[1..5]andproduct[1..5].Nevertheless,theseinstancesareusefulinmoregeneralizedsettings,aswewillseeinthesectionon
Foldable.
AnyandAllarenewtypewrappersprovidingMonoidinstancesforBool(underdisjunctionandconjunction,respectively).
TherearethreeinstancesforMaybe:abasicinstancewhichliftsaMonoidinstanceforatoaninstanceforMaybea,andtwonewtypewrappers
FirstandLastforwhichmappendselectsthefirst(respectivelylast)nonNothingitem.
Endoaisanewtypewrapperforfunctionsa>a,whichformamonoidundercomposition.
ThereareseveralwaystoliftMonoidinstancestoinstanceswithadditionalstructure.Wehavealreadyseenthataninstanceforacanbe
liftedtoaninstanceforMaybea.Therearealsotupleinstances:ifaandbareinstancesofMonoid,thensois(a,b),usingthemonoid
operationsforaandbintheobviouspairwisemanner.Finally,ifaisaMonoid,thensoisthefunctiontypee>aforanyeinparticular,g
`mappend`histhefunctionwhichappliesbothgandhtoitsargumentandthencombinestheresultsusingtheunderlyingMonoidinstancefor
a.Thiscanbequiteusefulandelegant(seeexample(http://thread.gmane.org/gmane.comp.lang.haskell.cafe/52416)).
ThetypeOrdering=LT|EQ|GTisaMonoid,definedinsuchawaythatmconcat(zipWithcomparexsys)computesthelexicographic
orderingofxsandys(ifxsandyshavethesamelength).Inparticular,mempty=EQ,andmappendevaluatestoitsleftmostnonEQargument
(orEQifbothargumentsareEQ).ThiscanbeusedtogetherwiththefunctioninstanceofMonoidtodosomecleverthings(example

(http://www.reddit.com/r/programming/comments/7cf4r/monoids_in_my_programming_language/c06adnx)).
TherearealsoMonoidinstancesforseveralstandarddatastructuresinthecontainerslibrary(haddock
(http://hackage.haskell.org/packages/archive/containers/0.2.0.0/doc/html/index.html)),includingMap,Set,andSequence.
Monoidisalsousedtoenableseveralothertypeclassinstances.Asnotedpreviously,wecanuseMonoidtomake((,)e)aninstanceof
Applicative:
instanceMonoide=>Applicative((,)e)where
purex=(mempty,x)
(u,f)<*>(v,x)=(u`mappend`v,fx)
Monoidcanbesimilarlyusedtomake((,)e)aninstanceofMonadaswellthisisknownasthewritermonad.Aswevealreadyseen,Writerand
WriterTareanewtypewrapperandtransformerforthismonad,respectively.
MonoidalsoplaysakeyroleintheFoldabletypeclass(seesectionFoldable).

9.4Othermonoidalclasses:Alternative,MonadPlus,ArrowPlus
TheAlternativetypeclass(haddock(http://www.haskell.org/ghc/docs/latest/html/libraries/base/ControlApplicative.html#g:2))isforApplicative
functorswhichalsohaveamonoidstructure:
classApplicativef=>Alternativefwhere
empty::fa
(<|>)::fa>fa>fa

Ofcourse,instancesofAlternativeshouldsatisfythemonoidlaws
empty<|>x=x
x<|>empty=x
(x<|>y)<|>z=x<|>(y<|>z)

Likewise,MonadPlus(haddock(http://www.haskell.org/ghc/docs/latest/html/libraries/base/ControlMonad.html#t:MonadPlus))isforMonadswitha
monoidstructure:
classMonadm=>MonadPlusmwhere
mzero::ma
mplus::ma>ma>ma

TheMonadPlusdocumentationstatesthatitisintendedtomodelmonadswhichalsosupportchoiceandfailureinadditiontothemonoidlaws,
instancesofMonadPlusareexpectedtosatisfy
mzero>>=f=mzero
v>>mzero=mzero

whichexplainsthesenseinwhichmzerodenotesfailure.Sincemzeroshouldbetheidentityformplus,thecomputationm1`mplus`m2succeeds
(evaluatestosomethingotherthanmzero)ifeitherm1orm2doessomplusrepresentschoice.Theguardfunctioncanalsobeusedwithinstancesof
MonadPlusitrequiresaconditiontobesatisfiedandfails(usingmzero)ifitisnot.AsimpleexampleofaMonadPlusinstanceis[],whichisexactly
thesameastheMonoidinstancefor[]:theemptylistrepresentsfailure,andlistconcatenationrepresentschoice.Ingeneral,however,aMonadPlus
instanceforatypeneednotbethesameasitsMonoidinstanceMaybeisanexampleofsuchatype.AgreatintroductiontotheMonadPlustypeclass,
withinterestingexamplesofitsuse,isDougAuclairsMonadPlus:WhataSuperMonad!intheMonad.Readerissue11
(http://www.haskell.org/wikiupload/6/6a/TMRIssue11.pdf).
ThereusedtobeatypeclasscalledMonadZerocontainingonlymzero,representingmonadswithfailure.Thedonotationrequiressomenotionof
failuretodealwithfailingpatternmatches.Unfortunately,MonadZerowasscrappedinfavorofaddingthefailmethodtotheMonadclass.Ifweare
lucky,somedayMonadZerowillberestored,andfailwillbebanishedtothebitbucketwhereitbelongs(seeMonadPlusreformproposal).Theidea
isthatanydoblockwhichusespatternmatching(andhencemayfail)wouldrequireaMonadZeroconstraintotherwise,onlyaMonadconstraint
wouldberequired.
Finally,ArrowZeroandArrowPlus(haddock(http://www.haskell.org/ghc/docs/latest/html/libraries/base/ControlArrow.html#t:ArrowZero))
representArrows(seebelow)withamonoidstructure:
classArrowarr=>ArrowZeroarrwhere
zeroArrow::b`arr`c

classArrowZeroarr=>ArrowPlusarrwhere
(<+>)::(b`arr`c)>(b`arr`c)>(b`arr`c)

9.5Furtherreading
Monoidshavegottenafairbitofattentionrecently,ultimatelyduetoablogpostbyBrianHurt(http://enfranchisedmind.com/blog/posts/random
thoughtsonhaskell/),inwhichhecomplainedaboutthefactthatthenamesofmanyHaskelltypeclasses(Monoidinparticular)aretakenfrom
abstractmathematics.ThisresultedinalongHaskellcafethread(http://thread.gmane.org/gmane.comp.lang.haskell.cafe/50590)arguingthepoint
anddiscussingmonoidsingeneral.
However,thiswasquicklyfollowedbyseveralblogpostsaboutMonoid .First,DanPiponiwroteagreat
Mayitsnameliveforever.
introductorypost,HaskellMonoidsandtheirUses(http://blog.sigfpe.com/2009/01/haskellmonoidsandtheir
uses.html).ThiswasquicklyfollowedbyHeinrichApfelmussMonoidsandFingerTrees
(http://apfelmus.nfshost.com/monoidfingertree.html),anaccessibleexpositionofHinzeandPatersonsclassicpaperon23fingertrees
(http://www.soi.city.ac.uk/%7Eross/papers/FingerTree.html),whichmakesverycleveruseofMonoidtoimplementanelegantandgenericdata
structure.DanPiponithenwrotetwofascinatingarticlesaboutusingMonoids(andfingertrees):FastIncrementalRegularExpressions
(http://blog.sigfpe.com/2009/01/fastincrementalregularexpression.html)andBeyondRegularExpressions
(http://blog.sigfpe.com/2009/01/beyondregularexpressionsmore.html)
Inasimilarvein,DavidPlacesarticleonimprovingData.Mapinordertocomputeincrementalfolds(seetheMonadReaderissue11
(http://www.haskell.org/wikiupload/6/6a/TMRIssue11.pdf))isalsoagoodexampleofusingMonoidtogeneralizeadatastructure.
SomeotherinterestingexamplesofMonoiduseincludebuildingelegantlistsortingcombinators
(http://www.reddit.com/r/programming/comments/7cf4r/monoids_in_my_programming_language/c06adnx),collectingunstructuredinformation
(http://byorgey.wordpress.com/2008/04/17/collectingunstructuredinformationwiththemonoidofpartialknowledge/),combiningprobability
distributions(http://izbicki.me/blog/gausiandistributionsaremonoids),andabrilliantseriesofpostsbyChungChiehShanandDylanThurston
usingMonoidstoelegantlysolveadifficultcombinatorialpuzzle(http://conway.rutgers.edu/~ccshan/wiki/blog/posts/WordNumbers1/)(followedby
part2(http://conway.rutgers.edu/~ccshan/wiki/blog/posts/WordNumbers2/),part3
(http://conway.rutgers.edu/~ccshan/wiki/blog/posts/WordNumbers3/),part4(http://conway.rutgers.edu/~ccshan/wiki/blog/posts/WordNumbers4/)

).
Asunlikelyasitsounds,monadscanactuallybeviewedasasortofmonoid,withjoinplayingtheroleofthebinaryoperationandreturntherole
oftheidentityseeDanPiponisblogpost(http://blog.sigfpe.com/2008/11/frommonoidstomonads.html).

10Foldable
TheFoldableclass,definedintheData.Foldablemodule(haddock(http://www.haskell.org/ghc/docs/latest/html/libraries/base/DataFoldable.html)
),abstractsovercontainerswhichcanbefoldedintoasummaryvalue.Thisallowssuchfoldingoperationstobewritteninacontaineragnostic
way.

10.1Definition
ThedefinitionoftheFoldabletypeclassis:
classFoldabletwhere
fold::Monoidm=>tm>m
foldMap::Monoidm=>(a>m)>ta>m

foldr::(a>b>b)>b>ta>b
foldl::(a>b>a)>a>tb>a
foldr1::(a>a>a)>ta>a
foldl1::(a>a>a)>ta>a

Thismaylookcomplicated,butinfact,tomakeaFoldableinstanceyouonlyneedtoimplementonemethod:yourchoiceoffoldMaporfoldr.All
theothermethodshavedefaultimplementationsintermsofthese,andarepresumablyincludedintheclassincasemoreefficientimplementations
canbeprovided.

10.2Instancesandexamples
ThetypeoffoldMapshouldmakeitclearwhatitissupposedtodo:givenawaytoconvertthedatainacontainerintoaMonoid(afunctiona>m)
andacontainerofas(ta),foldMapprovidesawaytoiterateovertheentirecontentsofthecontainer,convertingalltheastomsandcombining
allthemswithmappend.Thefollowingcodeshowstwoexamples:asimpleimplementationoffoldMapforlists,andabinarytreeexampleprovided
bytheFoldabledocumentation.
instanceFoldable[]where
foldMapg=mconcat.mapg

dataTreea=Empty|Leafa|Node(Treea)a(Treea)

instanceFoldableTreewhere
foldMapfEmpty=mempty
foldMapf(Leafx)=fx
foldMapf(Nodelkr)=foldMapfl`mappend`fk`mappend`foldMapfr

ThefoldrfunctionhasatypesimilartothefoldrfoundinthePrelude,butmoregeneral,sincethefoldrinthePreludeworksonlyonlists.
TheFoldablemodulealsoprovidesinstancesforMaybeandArrayadditionally,manyofthedatastructuresfoundinthestandardcontainerslibrary
(http://hackage.haskell.org/package/containers)(forexample,Map,Set,Tree,andSequence)providetheirownFoldableinstances.
Exercises
1. WhatisthetypeoffoldMap.foldMap?OrfoldMap.foldMap.
foldMap,etc.?Whatdotheydo?

10.3Derivedfolds
GivenaninstanceofFoldable,wecanwritegeneric,containeragnosticfunctionssuchas:
Computethesizeofanycontainer.
containerSize::Foldablef=>fa>Int
containerSize=getSum.foldMap(const(Sum1))

Computealistofelementsofacontainersatisfyingapredicate.
filterF::Foldablef=>(a>Bool)>fa>[a]
filterFp=foldMap(\a>ifpathen[a]else[])

GetalistofalltheStringsinacontainerwhichincludethe
lettera.
aStrings::Foldablef=>fString>[String]
aStrings=filterF(elem'a')

TheFoldablemodulealsoprovidesalargenumberofpredefinedfolds,manyofwhicharegeneralizedversionsofPreludefunctionsofthesame
namethatonlyworkonlists:concat,concatMap,and,or,any,all,sum,product,maximum(By),minimum(By),elem,notElem,andfind.
TheimportantfunctiontoListisalsoprovided,whichturnsanyFoldablestructureintoalistofitselementsinleftrightorderitworksbyfolding
withthelistmonoid.
TherearealsogenericfunctionsthatworkwithApplicativeorMonadinstancestogeneratesomesortofcomputationfromeachelementina
container,andthenperformallthesideeffectsfromthosecomputations,discardingtheresults:traverse_,sequenceA_,andothers.Theresultsmust
bediscardedbecausetheFoldableclassistooweaktospecifywhattodowiththem:wecannot,ingeneral,makeanarbitraryApplicativeorMonad
instanceintoaMonoid,butwecanmakem()intoaMonoidforanysuchm.IfwedohaveanApplicativeorMonadwithamonoidstructurethatis,
anAlternativeoraMonadPlusthenwecanusetheasumormsumfunctions,whichcancombinetheresultsaswell.ConsulttheFoldable
documentation(http://www.haskell.org/ghc/docs/latest/html/libraries/base/DataFoldable.html)formoredetailsonanyofthesefunctions.
NotethattheFoldableoperationsalwaysforgetthestructureofthecontainerbeingfolded.Ifwestartwithacontaineroftypetaforsome
Foldablet,thentwillneverappearintheoutputtypeofanyoperationsdefinedintheFoldablemodule.Manytimesthisisexactlywhatwewant,
butsometimeswewouldliketobeabletogenericallytraverseacontainerwhilepreservingitsstructureandthisisexactlywhattheTraversable
classprovides,whichwillbediscussedinthenextsection.
Exercises
1. ImplementtoList::Foldablef=>fa>[a].
2. Picksomeofthefollowingfunctionstoimplement:concat,
concatMap,and,or,any,all,sum,product,maximum(By),minimum(By),
elem,notElem,andfind.FigureouthowtheygeneralizetoFoldable
andcomeupwithelegantimplementationsusingfoldorfoldMap
alongwithappropriateMonoidinstances.

10.4Foldableactuallyisn't
Thegenericterm"fold"isoftenusedtorefertothemoretechnicalconceptofcatamorphism.Intuitively,givenawaytosummarize"onelevelof
structure"(whererecursivesubtermshavealreadybeenreplacedwiththeirsummaries),acatamorphismcansummarizeanentirerecursive
structure.ItisimportanttorealizethatFoldabledoesnotcorrespondtocatamorphisms,buttosomethingweaker.Inparticular,Foldableallows
observingonlytheleftrightorderofelementswithinastructure,nottheactualstructureitself.Putanotherway,everyuseofFoldablecanbe
expressedintermsoftoList.Forexample,folditselfisequivalenttomconcat.toList.
Thisissufficientformanytasks,butnotall.Forexample,considertryingtocomputethedepthofaTree:tryaswemight,thereisnowayto
implementitusingFoldable.However,itcanbeimplementedasacatamorphism.

10.5Furtherreading
TheFoldableclasshaditsgenesisinMcBrideandPatersonspaper(http://www.soi.city.ac.uk/~ross/papers/Applicative.html)introducing
Applicative,althoughithasbeenfleshedoutquiteabitfromtheforminthepaper.
AninterestinguseofFoldable(aswellasTraversable)canbefoundinJanisVoigtlnderspaperBidirectionalizationforfree!
(http://doi.acm.org/10.1145/1480881.1480904).

11Traversable
11.1Definition
TheTraversabletypeclass,definedintheData.Traversablemodule(haddock(http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data
Traversable.html)),is:
class(Functort,Foldablet)=>Traversabletwhere
traverse::Applicativef=>(a>fb)>ta>f(tb)
sequenceA::Applicativef=>t(fa)>f(ta)
mapM::Monadm=>(a>mb)>ta>m(tb)
sequence::Monadm=>t(ma)>m(ta)

Asyoucansee,everyTraversableisalsoafoldablefunctor.LikeFoldable,thereisalotinthistypeclass,butmakinginstancesisactuallyrather
easy:oneneedonlyimplementtraverseorsequenceAtheothermethodsallhavedefaultimplementationsintermsofthesefunctions.Agood
exerciseistofigureoutwhatthedefaultimplementationsshouldbe:giveneithertraverseorsequenceA,howwouldyoudefinetheotherthree
methods?(HintformapM:Control.ApplicativeexportstheWrapMonadnewtype,whichmakesanyMonadintoanApplicative.Thesequencefunction
canbeimplementedintermsofmapM.)

11.2Intuition
ThekeymethodoftheTraversableclass,andthesourceofitsuniquepower,issequenceA.Consideritstype:
sequenceA::Applicativef=>t(fa)>f(ta)

Thisanswersthefundamentalquestion:whencanwecommutetwofunctors?Forexample,canweturnatreeoflistsintoalistoftrees?
Theabilitytocomposetwomonadsdependscruciallyonthisabilitytocommutefunctors.Intuitively,ifwewanttobuildacomposedmonadMa=
m(na)outofmonadsmandn,thentobeabletoimplementjoin::M(Ma)>Ma,thatis,join::m(n(m(na)))>m(na),wehavetobe
abletocommutethenpastthemtogetm(m(n(na))),andthenwecanusethejoinsformandntoproducesomethingoftypem(na).SeeMark
Jonesspaper(http://web.cecs.pdx.edu/~mpj/pubs/springschool.html)formoredetails.
Alternatively,lookingatthetypeoftraverse,
traverse::Applicativef=>(a>fb)>ta>f(tb)

leadsustoviewTraversableasageneralizationofFunctor.traverseisan"effectfulfmap":itallowsustomapoverastructureoftypeta,
applyingafunctiontoeveryelementoftypeaandinordertoproduceanewstructureoftypetbbutalongthewaythefunctionmayhavesome
effects(capturedbytheapplicativefunctorf).
Exercises
1. Thereareatleasttwonaturalwaystoturnatreeoflistsintoalist
oftrees.Whatarethey,andwhy?
2. Giveanaturalwaytoturnalistoftreesintoatreeoflists.
3. Whatisthetypeoftraverse.traverse?Whatdoesitdo?

11.3Instancesandexamples
WhatsanexampleofaTraversableinstance?ThefollowingcodeshowsanexampleinstanceforthesameTreetypeusedasanexampleinthe
previousFoldablesection.ItisinstructivetocomparethisinstancewithaFunctorinstanceforTree,whichisalsoshown.
dataTreea=Empty|Leafa|Node(Treea)a(Treea)

instanceTraversableTreewhere
traversegEmpty=pureEmpty
traverseg(Leafx)=Leaf<$>gx
traverseg(Nodelxr)=Node<$>traversegl
<*>gx
<*>traversegr

instanceFunctorTreewhere
fmapgEmpty=Empty
fmapg(Leafx)=Leaf$gx
fmapg(Nodelxr)=Node(fmapgl)
(gx)
(fmapgr)

ItshouldbeclearthattheTraversableandFunctorinstancesforTreearealmostidenticaltheonlydifferenceisthattheFunctorinstanceinvolves
normalfunctionapplication,whereastheapplicationsintheTraversableinstancetakeplacewithinanApplicativecontext,using(<$>)and(<*>).
Infact,thiswillbetrueforanytype.
AnyTraversablefunctorisalsoFoldable,andaFunctor.Wecanseethisnotonlyfromtheclassdeclaration,butbythefactthatwecanimplement
themethodsofbothclassesgivenonlytheTraversablemethods.
ThestandardlibrariesprovideanumberofTraversableinstances,includinginstancesfor[],Maybe,Map,Tree,andSequence.Notably,Setisnot
Traversable,althoughitisFoldable.
Exercises

1. ImplementfmapandfoldMapusingonlytheTraversablemethods.
(NotethattheTraversablemoduleprovidestheseimplementations
asfmapDefaultandfoldMapDefault.)

11.4Laws
AnyinstanceofTraversablemustsatisfythefollowingtwolaws,whereIdentityistheidentityfunctor(asdefinedintheData.Functor.Identity
module(http://hackage.haskell.org/packages/archive/transformers/latest/doc/html/DataFunctorIdentity.html)fromthetransformerspackage),and
Composewrapsthecompositionoftwofunctors(asdefinedinData.Functor.Compose
(http://hackage.haskell.org/packages/archive/transformers/0.3.0.0/doc/html/DataFunctorCompose.html)):
1. traverseIdentity=Identity
2. traverse(Compose.fmapg.f)=Compose.fmap(traverseg).traversef
Thefirstlawessentiallysaysthattraversalscannotmakeuparbitraryeffects.Thesecondlawexplainshowdoingtwotraversalsinsequencecanbe
collapsedtoasingletraversal.
Additionally,supposeetaisan"Applicativemorphism",thatis,
eta::forallafg.(Applicativef,Applicativeg)=>fa>ga

andetapreservestheApplicativeoperations:eta(purex)=purexandeta(x<*>y)=etax<*>etay.Then,byparametricity,anyinstance
ofTraversablesatisfyingtheabovetwolawswillalsosatisfyeta.traversef=traverse(eta.f).

11.5Furtherreading
TheTraversableclassalsohaditsgenesisinMcBrideandPatersonsApplicativepaper(http://www.soi.city.ac.uk/~ross/papers/Applicative.html)
,andisdescribedinmoredetailinGibbonsandOliveira,TheEssenceoftheIteratorPattern
(http://www.comlab.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf),whichalsocontainsawealthofreferencestorelatedwork.
TraversableformsacorecomponentofEdwardKmett'slenslibrary(http://hackage.haskell.org/package/lens).WatchingEdward'stalkonthe

subject(https://vimeo.com/56063074)isahighlyrecommendedwaytogainbetterinsightintoTraversable,Foldable,Applicative,andmanyother
thingsbesides.
ForreferencesontheTraversablelaws,seeRussellO'Connor'smailinglistpost(http://article.gmane.org/gmane.comp.lang.haskell.libraries/17778)
(andsubsequentthread).

12Category
CategoryisarelativelyrecentadditiontotheHaskellstandardlibraries.Itgeneralizesthenotionoffunctioncompositiontogeneralmorphisms.

ThedefinitionoftheCategorytypeclass(fromControl.Categoryhaddock
(http://www.haskell.org/ghc/docs/latest/html/libraries/base/ControlCategory.html))isshownbelow.Forease
ofreading,notethatIhaveusedaninfixtypevariable`arr`,inparallelwiththeinfixfunctiontypeconstructor
(>). ThissyntaxisnotpartofHaskell2010.Theseconddefinitionshownistheoneusedinthestandard
libraries.Fortheremainderofthisdocument,Iwillusetheinfixtypeconstructor`arr`forCategoryaswellas
Arrow.
classCategoryarrwhere
id::a`arr`a
(.)::(b`arr`c)>(a`arr`b)>(a`arr`c)

Thesamething,withanormal(prefix)typeconstructor
classCategorycatwhere
id::cataa
(.)::catbc>catab>catac

NotethataninstanceofCategoryshouldbeatypeconstructorwhichtakestwotypearguments,thatis,
somethingofkind*>*>*.Itisinstructivetoimaginethetypeconstructorvariablecatreplacedbythe
functionconstructor(>):indeed,inthiscasewerecoverpreciselythefamiliaridentityfunctionidandfunction
compositionoperator(.)definedinthestandardPrelude.
Ofcourse,theCategorymoduleprovidesexactlysuchaninstanceofCategoryfor(>).Butitalsoprovidesone
otherinstance,shownbelow,whichshouldbefamiliarfromthepreviousdiscussionoftheMonadlaws.Kleisli

GHC7.6.1changedits
rulesregardingtypesand
typevariables.Now,any
operatoratthetypelevelis
treatedasatypeconstructor
ratherthanatypevariable
priortoGHC7.6.1itwas
possibletouse(~>)instead
of`arr`.Formore
information,seethe
discussionontheGHCusers
mailinglist
(http://thread.gmane.org/gmane.comp.la
.Foranewapproachtonice
arrownotationthatworks
withGHC7.6.1,seethis
message
(http://article.gmane.org/gmane.comp.la
andalsothismessage
(http://article.gmane.org/gmane.comp.la
fromEdwardKmett,though

mab,asdefinedintheControl.Arrowmodule,isjustanewtypewrapperarounda>mb.
newtypeKleislimab=Kleisli{runKleisli::a>mb}

instanceMonadm=>Category(Kleislim)where
id=Kleislireturn
Kleislig.Kleislih=Kleisli(h>=>g)

forsimplicityIhaven't
adoptedithere.

TheonlylawthatCategoryinstancesshouldsatisfyisthatidand(.)shouldformamonoidthatis,idshouldbetheidentityof(.),and(.)
shouldbeassociative.
Finally,theCategorymoduleexportstwoadditionaloperators:(<<<),whichisjustasynonymfor(.),and(>>>),whichis(.)withitsarguments
reversed.(Inpreviousversionsofthelibraries,theseoperatorsweredefinedaspartoftheArrowclass.)

12.1Furtherreading
ThenameCategoryisabitmisleading,sincetheCategoryclasscannotrepresentarbitrarycategories,butonlycategorieswhoseobjectsareobjects
ofHask,thecategoryofHaskelltypes.ForamoregeneraltreatmentofcategorieswithinHaskell,seethecategoryextraspackage
(http://hackage.haskell.org/package/categoryextras).Formoreaboutcategorytheoryingeneral,seetheexcellentHaskellwikibookpage
(http://en.wikibooks.org/wiki/Haskell/Category_theory),SteveAwodeysnewbook(http://books.google.com/books/about/Category_theory.html?
id=MCJ6x2lC7oC),BenjaminPiercesBasiccategorytheoryforcomputerscientists
(http://books.google.com/books/about/Basic_category_theory_for_computer_scien.html?id=ezdeaHfpYPwC),orBarrandWellsscategorytheory
lecturenotes(http://folli.loria.fr/cds/1999/esslli99/courses/barrwells.html).BenjaminRussellsblogpost
(http://dekudekuplex.wordpress.com/2009/01/19/motivatinglearningcategorytheoryfornonmathematicians/)isanothergoodsourceof
motivationandcategorytheorylinks.YoucertainlydontneedtoknowanycategorytheorytobeasuccessfulandproductiveHaskellprogrammer,
butitdoeslenditselftomuchdeeperappreciationofHaskellsunderlyingtheory.

13Arrow
TheArrowclassrepresentsanotherabstractionofcomputation,inasimilarveintoMonadandApplicative.However,unlikeMonadandApplicative,
whosetypesonlyreflecttheiroutput,thetypeofanArrowcomputationreflectsbothitsinputandoutput.Arrowsgeneralizefunctions:ifarrisan
instanceofArrow,avalueoftypeb`arr`ccanbethoughtofasacomputationwhichtakesvaluesoftypebasinput,andproducesvaluesoftypec
asoutput.Inthe(>)instanceofArrowthisisjustapurefunctioningeneral,however,anarrowmayrepresentsomesortofeffectful
computation.

13.1Definition
ThedefinitionoftheArrowtypeclass,fromControl.Arrow(haddock(http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control
Arrow.html)),is:
classCategoryarr=>Arrowarrwhere
arr::(b>c)>(b`arr`c)
first::(b`arr`c)>((b,d)`arr`(c,d))
second::(b`arr`c)>((d,b)`arr`(d,c))
(***)::(b`arr`c)>(b'`arr`c')>((b,b')`arr`(c,c'))
(&&&)::(b`arr`c)>(b`arr`c')>(b`arr`(c,c'))

ThefirstthingtonoteistheCategoryclassconstraint,whichmeansthatwegetidentityarrowsandarrow
compositionforfree:giventwoarrowsg::b`arr`candh::c`arr`d,wecanformtheircompositiong
>>>h::b`arr`d .
Asshouldbeafamiliarpatternbynow,theonlymethodswhichmustbedefinedwhenwritinganewinstanceof
Arrowarearrandfirsttheothermethodshavedefaultdefinitionsintermsofthese,butareincludedinthe
Arrowclasssothattheycanbeoverriddenwithmoreefficientimplementationsifdesired.

13.2Intuition
Letslookateachofthearrowmethodsinturn.RossPatersonswebpageonarrows
(http://www.haskell.org/arrows/)hasnicediagramswhichcanhelpbuildintuition.

Inversionsofthebase
packagepriortoversion4,
thereisnoCategoryclass,
andtheArrowclassincludes
thearrowcomposition
operator(>>>).Italso
includespureasasynonym
forarr,butthiswasremoved
sinceitconflictswiththe
purefromApplicative.

Thearrfunctiontakesanyfunctionb>candturnsitintoageneralizedarrowb`arr`c.Thearrmethodjustifiestheclaimthatarrows
generalizefunctions,sinceitsaysthatwecantreatanyfunctionasanarrow.Itisintendedthatthearrowarrgispureinthesensethatit
onlycomputesgandhasnoeffects(whateverthatmightmeanforanyparticulararrowtype).
Thefirstmethodturnsanyarrowfrombtocintoanarrowfrom(b,d)to(c,d).Theideaisthatfirstgusesgtoprocessthefirstelement
ofatuple,andletsthesecondelementpassthroughunchanged.ForthefunctioninstanceofArrow,ofcourse,firstg(x,y)=(gx,y).

Thesecondfunctionissimilartofirst,butwiththeelementsofthetuplesswapped.Indeed,itcanbedefinedintermsoffirstusingan
auxiliaryfunctionswap,definedbyswap(x,y)=(y,x).
The(***)operatorisparallelcompositionofarrows:ittakestwoarrowsandmakesthemintoonearrowontuples,whichhasthebehavior
ofthefirstarrowonthefirstelementofatuple,andthebehaviorofthesecondarrowonthesecondelement.Themnemonicisthatg***his
theproduct(hence*)ofgandh.ForthefunctioninstanceofArrow,wedefine(g***h)(x,y)=(gx,hy).Thedefaultimplementationof
(***)isintermsoffirst,second,andsequentialarrowcomposition(>>>).Thereadermayalsowishtothinkabouthowtoimplementfirst
andsecondintermsof(***).
The(&&&)operatorisfanoutcompositionofarrows:ittakestwoarrowsgandhandmakesthemintoanewarrowg&&&hwhichsupplies
itsinputastheinputtobothgandh,returningtheirresultsasatuple.Themnemonicisthatg&&&hperformsbothgandh(hence&)onits
input.Forfunctions,wedefine(g&&&h)x=(gx,hx).

13.3Instances
TheArrowlibraryitselfonlyprovidestwoArrowinstances,bothofwhichwehavealreadyseen:(>),thenormalfunctionconstructor,andKleisli
m,whichmakesfunctionsoftypea>mbintoArrowsforanyMonadm.Theseinstancesare:
instanceArrow(>)where
arrg=g
firstg(x,y)=(gx,y)

newtypeKleislimab=Kleisli{runKleisli::a>mb}

instanceMonadm=>Arrow(Kleislim)where
arrf=Kleisli(return.f)
first(Kleislif)=Kleisli(\~(b,d)>doc<fb
return(c,d))

13.4Laws
TherearequiteafewlawsthatinstancesofArrowshouldsatisfy :
arrid=id
arr(h.g)=arrg>>>arrh
first(arrg)=arr(g***id)
first(g>>>h)=firstg>>>firsth
firstg>>>arr(id***h)=arr(id***h)>>>firstg
firstg>>>arrfst=arrfst>>>g
first(firstg)>>>arrassoc=arrassoc>>>firstg

assoc((x,y),z)=(x,(y,z))

Notethatthisversionofthelawsisslightlydifferentthanthelawsgiveninthefirsttwoabovereferences,since
severalofthelawshavenowbeensubsumedbytheCategorylaws(inparticular,therequirementsthatidisthe
identityarrowandthat(>>>)isassociative).ThelawsshownherefollowthoseinPatersonsProgrammingwith
Arrows,whichusestheCategoryclass.
ThereaderisadvisednottolosetoomuchsleepovertheArrowlaws ,sinceitisnotessentialtounderstand
theminordertoprogramwitharrows.TherearealsolawsthatArrowChoice,ArrowApply,andArrowLoop
instancesshouldsatisfytheinterestedreadershouldconsultPaterson:ProgrammingwithArrows
(http://www.soi.city.ac.uk/~ross/papers/fop.html).

SeeJohnHughes:
Generalisingmonadsto
arrows
(http://dx.doi.org/10.1016/S0167
6423(99)000234)Sam
Lindley,PhilipWadler,
JeremyYallop:Thearrow
calculus
(http://homepages.inf.ed.ac.uk/wadler/p
RossPaterson:
ProgrammingwithArrows
(http://www.soi.city.ac.uk/~ross/papers/
.
Unlesscategorytheory
inducedinsomnolenceisyour
cupoftea.

13.5ArrowChoice
ComputationsbuiltusingtheArrowclass,likethosebuiltusingtheApplicativeclass,areratherinflexible:thestructureofthecomputationisfixed
attheoutset,andthereisnoabilitytochoosebetweenalternateexecutionpathsbasedonintermediateresults.TheArrowChoiceclassprovides
exactlysuchanability:
classArrowarr=>ArrowChoicearrwhere
left::(b`arr`c)>(Eitherbd`arr`Eithercd)
right::(b`arr`c)>(Eitherdb`arr`Eitherdc)
(+++)::(b`arr`c)>(b'`arr`c')>(Eitherbb'`arr`Eithercc')
(|||)::(b`arr`d)>(c`arr`d)>(Eitherbc`arr`d)

AcomparisonofArrowChoicetoArrowwillrevealastrikingparallelbetweenleft,right,(+++),(|||)andfirst,second,(***),(&&&),
respectively.Indeed,theyaredual:first,second,(***),and(&&&)alloperateonproducttypes(tuples),andleft,right,(+++),and(|||)arethe
correspondingoperationsonsumtypes.Ingeneral,theseoperationscreatearrowswhoseinputsaretaggedwithLeftorRight,andcanchoosehow
toactbasedonthesetags.

Ifgisanarrowfrombtoc,thenleftgisanarrowfromEitherbdtoEithercd.OninputstaggedwithLeft,theleftgarrowhasthe
behaviorofgoninputstaggedwithRight,itbehavesastheidentity.
Therightfunction,ofcourse,isthemirrorimageofleft.ThearrowrightghasthebehaviorofgoninputstaggedwithRight.
The(+++)operatorperformsmultiplexing:g+++hbehavesasgoninputstaggedwithLeft,andashoninputstaggedwithRight.Thetags
arepreserved.The(+++)operatoristhesum(hence+)oftwoarrows,justas(***)istheproduct.
The(|||)operatorismergeorfanin:thearrowg|||hbehavesasgoninputstaggedwithLeft,andhoninputstaggedwithRight,but
thetagsarediscarded(hence,gandhmusthavethesameoutputtype).Themnemonicisthatg|||hperformseithergorhonitsinput.
TheArrowChoiceclassallowscomputationstochooseamongafinitenumberofexecutionpaths,basedonintermediateresults.Thepossible
executionpathsmustbeknowninadvance,andexplicitlyassembledwith(+++)or(|||).However,sometimesmoreflexibilityisneeded:we
wouldliketobeabletocomputeanarrowfromintermediateresults,andusethiscomputedarrowtocontinuethecomputation.Thisisthepower
giventousbyArrowApply.

13.6ArrowApply
TheArrowApplytypeclassis:
classArrowarr=>ArrowApplyarrwhere
app::(b`arr`c,b)`arr`c

Ifwehavecomputedanarrowastheoutputofsomepreviouscomputation,thenappallowsustoapplythatarrowtoaninput,producingitsoutput
astheoutputofapp.Asanexercise,thereadermaywishtouseapptoimplementanalternativecurriedversion,app2::b`arr`((b`arr`c)
`arr`c).
Thisnotionofbeingabletocomputeanewcomputationmaysoundfamiliar:thisisexactlywhatthemonadicbindoperator(>>=)does.Itshould
notparticularlycomeasasurprisethatArrowApplyandMonadareexactlyequivalentinexpressivepower.Inparticular,Kleislimcanbemadean
instanceofArrowApply,andanyinstanceofArrowApplycanbemadeaMonad(viathenewtypewrapperArrowMonad).Asanexercise,thereadermay
wishtotryimplementingtheseinstances:
instanceMonadm=>ArrowApply(Kleislim)where
app=exercise

newtypeArrowApplya=>ArrowMonadab=ArrowMonad(a()b)

instanceArrowApplya=>Monad(ArrowMonada)where
return=exercise
(ArrowMonada)>>=k=exercise

13.7ArrowLoop
TheArrowLooptypeclassis:
classArrowa=>ArrowLoopawhere
loop::a(b,d)(c,d)>abc

trace::((b,d)>(c,d))>b>c
tracefb=let(c,d)=f(b,d)inc

Itdescribesarrowsthatcanuserecursiontocomputeresults,andisusedtodesugartherecconstructinarrownotation(describedbelow).
Takenbyitself,thetypeoftheloopmethoddoesnotseemtotellusmuch.Itsintention,however,isageneralizationofthetracefunctionwhichis
alsoshown.Thedcomponentofthefirstarrowsoutputisfedbackinasitsowninput.Inotherwords,thearrowloopgisobtainedbyrecursively
fixingthesecondcomponentoftheinputtog.
Itcanbeabitdifficulttogrokwhatthetracefunctionisdoing.Howcandappearontheleftandrightsidesofthelet?Well,thisisHaskells
lazinessatwork.Thereisnotspacehereforafullexplanationtheinterestedreaderisencouragedtostudythestandardfixfunction,andtoread
Patersonsarrowtutorial(http://www.soi.city.ac.uk/~ross/papers/fop.html).

13.8Arrownotation
Programmingdirectlywiththearrowcombinatorscanbepainful,especiallywhenwritingcomplexcomputationswhichneedtoretain
simultaneousreferencetoanumberofintermediateresults.Withnothingbutthearrowcombinators,suchintermediateresultsmustbekeptin
nestedtuples,anditisuptotheprogrammertorememberwhichintermediateresultsareinwhichcomponents,andtoswap,reassociate,and
generallymangletuplesasnecessary.ThisproblemissolvedbythespecialarrownotationsupportedbyGHC,similartodonotationformonads,
thatallowsnamestobeassignedtointermediateresultswhilebuildinguparrowcomputations.Anexamplearrowimplementedusingarrow

notation,takenfromPaterson,is:
classArrowLooparr=>ArrowCircuitarrwhere
delay::b>(b`arr`b)

counter::ArrowCircuitarr=>Bool`arr`Int
counter=procreset>do
recoutput<idA<ifresetthen0elsenext
next<delay0<output+1
idA<output

Thisarrowisintendedtorepresentarecursivelydefinedcountercircuitwitharesetline.
ThereisnotspacehereforafullexplanationofarrownotationtheinterestedreadershouldconsultPatersonspaperintroducingthenotation
(http://www.soi.city.ac.uk/~ross/papers/notation.html),orhislatertutorialwhichpresentsasimplifiedversion
(http://www.soi.city.ac.uk/~ross/papers/fop.html).

13.9Furtherreading
Anexcellentstartingplaceforthestudentofarrowsisthearrowswebpage(http://www.haskell.org/arrows/),whichcontainsanintroductionand
manyreferences.SomekeypapersonarrowsincludeHughessoriginalpaperintroducingarrows,Generalisingmonadstoarrows
(http://dx.doi.org/10.1016/S01676423(99)000234),andPatersonspaperonarrownotation
(http://www.soi.city.ac.uk/~ross/papers/notation.html).
BothHughesandPatersonlaterwroteaccessibletutorialsintendedforabroaderaudience:Paterson:ProgrammingwithArrows
(http://www.soi.city.ac.uk/~ross/papers/fop.html)andHughes:ProgrammingwithArrows(http://www.cse.chalmers.se/~rjmh/afparrows.pdf).
AlthoughHughessgoalindefiningtheArrowclasswastogeneralizeMonads,andithasbeensaidthatArrowliesbetweenApplicativeandMonad
inpower,theyarenotdirectlycomparable.ThepreciserelationshipremainedinsomeconfusionuntilanalyzedbyLindley,Wadler,andYallop
(http://homepages.inf.ed.ac.uk/wadler/papers/arrowsandidioms/arrowsandidioms.pdf),whoalsoinventedanewcalculusofarrows,basedon
thelambdacalculus,whichconsiderablysimplifiesthepresentationofthearrowlaws(seeThearrowcalculus
(http://homepages.inf.ed.ac.uk/wadler/papers/arrows/arrows.pdf)).ThereisalsoaprecisetechnicalsenseinwhichArrowcanbeseenasthe
intersectionofApplicativeandCategory(http://justbottom.blogspot.de/2010/04/programmingwitheffectsstorysofar.html).
SomeexamplesofArrowsincludeYampa(http://www.haskell.org/yampa/),theHaskellXMLToolkit(http://www.fh
wedel.de/~si/HXmlToolbox/),andthefunctionalGUIlibraryGrapefruit.
Someextensionstoarrowshavebeenexploredforexample,theBiArrowsofAlimarineetal.("ThereandBackAgain:ArrowsforInvertible
Programming"(http://wiki.clean.cs.ru.nl/download/papers/2005/alia2005biarrowsHaskellWorkshop.pdf)),fortwowayinsteadofoneway
computation.
TheHaskellwikihaslinkstomanyadditionalresearchpapersrelatingtoArrows.

14Comonad
ThefinaltypeclasswewillexamineisComonad.TheComonadclassisthecategoricaldualofMonadthatis,ComonadislikeMonadbutwithallthe
functionarrowsflipped.ItisnotactuallyinthestandardHaskelllibraries,butithasseensomeinterestingusesrecently,soweincludeitherefor
completeness.

14.1Definition
TheComonadtypeclass,definedintheControl.Comonadmoduleofthecomonadlibrary(http://hackage.haskell.org/package/comonad),is:
classFunctorw=>Comonadwwhere
extract::wa>a

duplicate::wa>w(wa)
duplicate=extendid

extend::(wa>b)>wa>wb
extendf=fmapf.duplicate

Asyoucansee,extractisthedualofreturn,duplicateisthedualofjoin,andextendisthedualof(=<<).ThedefinitionofComonadisabit
redundant,givingtheprogrammerthechoiceonwhetherextendorduplicateareimplementedtheotheroperationthenhasadefault
implementation.
AprototypicalexampleofaComonadinstanceis:

Infinitelazystreams
dataStreama=Consa(Streama)

'duplicate'islikethelistfunction'tails'
'extend'computesanewStreamfromanold,wheretheelement
atpositionniscomputedasafunctionofeverythingfrom
positionnonwardsintheoldStream
instanceComonadStreamwhere
extract(Consx_)=x
duplicates@(Consxxs)=Conss(duplicatexs)
extendgs@(Consxxs)=Cons(gs)(extendgxs)
=fmapg(duplicates)

14.2Furtherreading
DanPiponiexplainsinablogpostwhatcellularautomatahavetodowithcomonads(http://blog.sigfpe.com/2006/12/evaluatingcellularautomata
is.html).Inanotherblogpost,ConalElliotthasexaminedacomonadicformulationoffunctionalreactiveprogramming
(http://conal.net/blog/posts/functionalinteractivebehavior/).SterlingCloversblogpostComonadsineverydaylife
(http://fmapfixreturn.wordpress.com/2008/07/09/comonadsineverydaylife/)explainstherelationshipbetweencomonadsandzippers,andhow
comonadscanbeusedtodesignamenusystemforawebsite.
UustaluandVenehaveanumberofpapersexploringideasrelatedtocomonadsandfunctionalprogramming:
ComonadicNotionsofComputation(http://dx.doi.org/10.1016/j.entcs.2008.05.029)
Thedualofsubstitutionisredecoration(http://www.ioc.ee/~tarmo/papers/sfp01book.pdf)(Alsoavailableasps.gz
(http://www.cs.ut.ee/~varmo/papers/sfp01book.ps.gz).)
Recursivecoalgebrasfromcomonads(http://dx.doi.org/10.1016/j.ic.2005.08.005)
Recursionschemesfromcomonads(http://www.fing.edu.uy/~pardo/papers/njc01.ps.gz)
TheEssenceofDataflowProgramming(http://cs.ioc.ee/~tarmo/papers/essence.pdf).
GabrielGonzalez'sComonadsareobjects(http://www.haskellforall.com/2013/02/youcouldhaveinventedcomonads.html)pointsoutsimilarities
betweencomonadsandobjectorientedprogramming.
Thecomonadtransformers(http://hackage.haskell.org/package/comonadtransformers)packagecontainscomonadtransformers.

15Acknowledgements
AspecialthankstoallofthosewhotaughtmeaboutstandardHaskelltypeclassesandhelpedmedevelopgoodintuitionforthem,particularly
JulesBean(quicksilver),DerekElkins(ddarius),ConalElliott(conal),CaleGibbard(Cale),DavidHouse,DanPiponi(sigfpe),andKevinReid
(kpreid).
IalsothankthemanypeoplewhoprovidedamountainofhelpfulfeedbackandsuggestionsonafirstdraftoftheTypeclassopedia:DavidAmos,
KevinBallard,ReidBarton,DougBeardsley,JoachimBreitner,AndrewCave,DavidChristiansen,GregoryCollins,MarkJasonDominus,Conal
Elliott,YitzGale,GeorgeGiorgidze,StevenGrady,TravisHartwell,SteveHicks,PhilipHlzenspies,EdwardKmett,EricKow,SergeLe
Huitouze,FelipeLessa,StefanLjungstrand,EricMacaulay,RobMacAulay,SimonMeier,EricMertens,TimNewsham,RussellOConnor,
ConradParker,WaltRorieBaety,ColinRoss,TomSchrijvers,AdityaSiram,C.Smith,MartijnvanSteenbergen,JoeThornber,JaredUpdike,Rob
Vollmert,AndrewWagner,LouisWasserman,andAshleyYakeley,aswellasafewonlyknowntomebytheirIRCnicks:b_jonas,maltem,
tehgeekmeister,andziman.Ihaveundoubtedlyomittedafewinadvertently,whichinnowaydiminishesmygratitude.
Finally,IwouldliketothankWouterSwierstraforhisfantasticworkeditingtheMonad.Reader,andmywifeJoyiaforherpatienceduringthe
processofwritingtheTypeclassopedia.

16Abouttheauthor
BrentYorgey(blog(http://byorgey.wordpress.com/),homepage(http://www.cis.upenn.edu/~byorgey/))is(asofNovember2011)afourthyear
Ph.D.studentintheprogramminglanguagesgroup(http://www.cis.upenn.edu/~plclub/)attheUniversityofPennsylvania(http://www.upenn.edu).
Heenjoysteaching,creatingEDSLs,playingBachfugues,musinguponcategorytheory,andcookingtastylambdatreatsforthedenizensof
#haskell.

17Colophon
TheTypeclassopediawaswrittenbyBrentYorgeyandinitiallypublishedinMarch2009.Painstakinglyconvertedtowikisyntaxby
User:GeheimdienstinNovember2011,afteraskingBrentspermission.
IfsomethinglikethisTeXtowikisyntaxconversioneverneedstobedoneagain,herearesomevimcommandsthathelped:

%s/\\section{\([^}]*\)}/=\1=/gc
%s/\\subsection{\([^}]*\)}/==\1==/gc
%s/^*\\item/\r*/gc
%s///gc
%s/\$\([^$]*\)\$/<math>\1\\<\/math>/gcAppending\forcesimagestoberendered.Otherwise,Mediawikiwouldgobackandforth
betweenonefontforshort<math>tags,andanothermoreTexlikefontforlongertags(containingmorethanafewcharacters)""
%s/|\([^|]*\)|/<code>\1<\/code>/gc
%s/\\dots/.../gc
%s/^\\label{.*$//gc
%s/\\emph{\([^}]*\)}/''\1''/gc
%s/\\term{\([^}]*\)}/''\1''/gc
Thebiggestissuewastakingtheacademicpaperstylecitationsandturningthemintohyperlinkswithanappropriatetitleandanappropriatetarget.
Inmostcasestherewasanobviousthingtodo(e.g.onlinePDFsofthecitedpapersorCiteSeerentries).Sometimes,however,itslessclearand
youmightwanttochecktheoriginalTypeclassopediaPDFwiththeoriginalbibliographyfile
(http://code.haskell.org/~byorgey/TMR/Issue13/typeclassopedia.bib).
Togetallthecitationsintothemaintext,IfirsttriedprocessingthesourcewithTeXorLyx.Thisdidntworkduetomissingunfindablepackages,
syntaxerrors,andmygeneralineptitudewithTex.
Ithenwentforthenextbestsolution,whichseemedtobeextractingallinstancesof\cite{something}fromthesourceandinthatorderpulling
thereferencedentriesfromthe.bibfile.Thiswayyoucangothroughthesourcefileandsortedreferencesfileinparallel,copyingoverwhatyou
need,withoutsearchingbackandforthinthe.bibfile.Iused:
egrepo"\cite\{[^\}]*\}"~/typeclassopedia.lhs|cutc6|tr",""\n"|trd"}">/tmp/citations
foriin$(cat/tmp/citations)dogrepA99"$i"~/typeclassopedia.bib|egrepB99'^\}$'m1done>~/typeclassorefssorted
Retrievedfrom"https://wiki.haskell.org/index.php?title=Typeclassopedia&oldid=59129"
Categories:
ApplicativeFunctor
Arrow
Functor
Monad
Standardclasses
Standardlibraries
Standardpackages
Standardtypes
Thispagewaslastmodifiedon27November2014,at17:50.
Recentcontentisavailableunderasimplepermissivelicense.

You might also like