CheatSheet.pdf

(152 KB) Pobierz
355476662 UNPDF
HaskellCheatSheet
Strings
Enumerations
Thischeatsheetlaysoutthefundamentalele-
mentsoftheHaskelllanguage:syntax,keywords
andotherelements.Itispresentedasbothanex-
ecutableHaskellfileandaprintabledocument.
Loadthesourceintoyourfavoriteinterpreterto
playwithcodesamplesshown.
•"abc"–Unicodestring, sugar for
[’a’,’b’,’c’].
•’a’–Singlecharacter.
•[1..10]–Listofnumbers–1,2,...,10.
•[100..]–Infinitelistofnumbers–100,
101,102,....
•[110..100]–Emptylist;rangesonlygofor-
wards.
•[0,-1..]–Negativeintegers.
•[-100..-110]–Syntaxerror; need
[-100..-110]fornegatives.
•[1,3..100],[-1,3..100]–Listfrom1to
100by2,-1to100by4.
Infact,anyvaluewhichisintheEnumclasscanbe
used:
•[’a’..’z’]–Listofcharacters–a,b,
...,z.
•[1.0,1.5..2]–[1.0,1.5,2.0].
•[UppercaseLetter..] – List of
GeneralCategoryvalues(fromData.Char).
Multi-lineStrings Normally,itisasyntaxerror
ifastringhasanyactualnewlinecharacters.That
is,thisisasyntaxerror:
BasicSyntax
string1="Mylong
string."
Comments
Backslashes(‘\’)can“escape”anewline:
Asinglelinecommentstartswith‘--’andextends
totheendoftheline.Multi-linecommentsstart
with’{-’andextendto’-}’.Commentscanbe
nested.
Commentsabovefunctiondefinitionsshould
startwith‘{-|’andthosenexttoparametertypes
with‘--^’forcompatibilitywithHaddock,asys-
temfordocumentingHaskellcode.
string1="Mylong\
\string."
Theareabetweenthebackslashesisignored.
Newlinesinthestringmustberepresentedexplic-
itly:
string2="Mylong\n\
\string."
Thatis,string1evaluatesto:
Lists&Tuples
ReservedWords
Mylongstring.
•[]–Emptylist.
•[1,2,3]–Listofthreenumbers.
•1:2:3:[]–Alternatewaytowrite
listsusing“cons”(:)and“nil”([]).
•"abc"–Listofthreecharacters(stringsare
lists).
•’a’:’b’:’c’:[]–Listofcharacters
(sameas"abc").
•(1,"a")–2-elementtupleofanumberand
astring.
•(head,tail,3,’a’)–4-elementtupleof
twofunctions,anumberandacharacter.
ThefollowingwordsarereservedinHaskell.Itis
asyntaxerrortogiveavariableorafunctionone
ofthesenames.
Whilestring2evaluatesto:
Mylong
string.
•case
•class
•data
•deriving
•do
•else
•if
•import
•in
•infix
•infixl
•infixr
•instance
•let
•of
•module
•newtype
•then
•type
•where
Numbers
•1–IntegerorFloatingpoint
•1.0,1e10–Floatingpoint
•1.–syntaxerror
•-1–sugarfor(negate1)
•2-1–sugarfor((-)21)
c2009JustinBailey. 1
355476662.008.png 355476662.009.png
 
“Layout”rule,bracesandsemi-colons.
Let Indentthebodyoftheletatleastonespace
fromthefirstdefinitioninthelet.Ifletappears
onitsownline,thebodyofanydefinitionmust
appearinthecolumnafterthelet:
Nesting&Capture Nestedmatchingandbind-
ingarealsoallowed.
Haskellcanbewrittenusingbracesandsemi-
colons,justlikeC.However,noonedoes.Instead,
the“layout”ruleisused,wherespacesrepresent
scope.Thegeneralruleis:alwaysindent.When
thecompilercomplains,indentmore.
dataMaybea=Justa|Nothing
squarex=
letx2=
x*x
Figure1:ThedefinitionofMaybe
Bracesandsemi-colons Semi-colonstermi-
nateanexpression,andbracesrepresentscope.
Theycanbeusedafterseveralkeywords:where,
let,doandof.Theycannotbeusedwhendefin-
ingafunctionbody.Forexample,thebelowwill
notcompile.
inx2
UsingMaybewecandetermineifanychoice
wasgivenusinganestedmatch:
Ascanbeseenabove,theinkeywordmustalsobe
inthesamecolumnaslet.Finally,whenmultiple
definitionsaregiven,allidentifiersmustappearin
thesamecolumn.
anyChoice1ch=
casechof
Nothing->"Nochoice!"
Just(First_)->"First!"
JustSecond->"Second!"
_->"Somethingelse."
square2x={x*x;}
Keywords
However,thiswillworkfine:
Haskellkeywordsarelistedbelow,inalphabetical
order.
Bindingcanbeusedtomanipulatethevalue
matched:
square2x=result
where{result=x*x;}
Case
anyChoice2ch=
casechof
Nothing->"Nochoice!"
Justscore@(First"gold")->
"Firstwithgold!"
Justscore@(First_)->
"Firstwithsomethingelse:"
++showscore
_->"Notfirst."
FunctionDefinition Indentthebodyatleast
onespacefromthefunctionname:
caseissimilartoaswitchstatementinC#orJava,
butcanmatchapattern:theshapeofthevaluebe-
inginspected.Considerasimpledatatype:
squarex=
x*x
dataChoices=FirstString|Second|
Third|Fourth
Unlessawhereclauseispresent.Inthatcase,in-
dentthewhereclauseatleastonespacefromthe
functionnameandanyfunctionbodiesatleast
onespacefromthewherekeyword:
casecanbeusedtodeterminewhichchoicewas
given:
whichChoicech=
casechof
First_->"1st!"
Second->"2nd!"
_->"Somethingelse."
MatchingOrder Matchingproceedsfromtop
tobottom.IfanyChoice1isreorderedasfollows,
thefirstpatternwillalwayssucceed:
squarex=
x2
wherex2=
x*x
anyChoice3ch=
casechof
_->"Somethingelse."
Nothing->"Nochoice!"
Aswithpattern-matchinginfunctiondefinitions,
the‘_’tokenisa“wildcard”matchinganyvalue.
c2009JustinBailey. 2
355476662.010.png 355476662.001.png
 
Just(First_)->"First!"
JustSecond->"Second!"
classFlavorawhere
flavor::a->String
Data
So-calledalgebraicdatatypescanbedeclaredasfol-
lows:
Guards Guards,orconditionalmatches,canbe
usedincasesjustlikefunctiondefinitions.The
onlydifferenceistheuseofthe->insteadof
=.Hereisasimplefunctionwhichdoesacase-
insensitivestringmatch:
strcmps1s2=case(s1,s2)of
([],[])->True
(s1:ss1,s2:ss2)
|toUppers1==toUppers2->
strcmpss1ss2
|otherwise->False
_->False
Noticethatthedeclarationonlygivesthetype
signatureofthefunction—noimplementationis
givenhere(withsomeexceptions,see “Defaults”
onpage 3 ).Continuing,wecandefineseveralin-
stances:
dataMyType=MyValue1|MyValue2
MyTypeisthetype’sname. MyValue1and
MyValuearevaluesofthetypeandarecalledcon-
structors.Multipleconstructorsareseparatedwith
the‘|’character.Notethattypeandconstructor
namesmuststartwithacapitalletter.Itisasyn-
taxerrorotherwise.
instanceFlavorBoolwhere
flavor_="sweet"
instanceFlavorCharwhere
flavor_="sour"
ConstructorswithArguments Thetypeabove
isnotveryinterestingexceptasanenumeration.
Constructorsthattakeargumentscanbedeclared,
allowingmoreinformationtobestored:
EvaluatingflavorTruegives:
>flavorTrue
"sweet"
Class
dataPoint=TwoDIntInt
|ThreeDIntIntInt
AHaskellfunctionisdefinedtoworkonacertain
typeorsetoftypesandcannotbedefinedmore
thanonce.Mostlanguagessupporttheideaof
“overloading”,whereafunctioncanhavediffer-
entbehaviordependingonthetypeofitsargu-
ments.Haskellaccomplishesoverloadingthrough
classandinstancedeclarations.Aclassdefines
oneormorefunctionsthatcanbeappliedtoany
typeswhicharemembers(i.e.,instances)ofthat
class.AclassisanalogoustoaninterfaceinJava
orC#,andinstancestoaconcreteimplementation
oftheinterface.
Aclassmustbedeclaredwithoneormore
typevariables.Technically,Haskell98onlyal-
lowsonetypevariable,butmostimplementations
ofHaskellsupportso-calledmulti-parametertype
classes,whichallowmorethanonetypevariable.
Wecandefineaclasswhichsuppliesaflavor
foragiventype:
Whileflavor’x’gives:
>flavor’x’
"sour"
Noticethattheargumentsforeachconstructorare
typenames,notconstructors.Thatmeansthis
kindofdeclarationisillegal:
Defaults Defaultimplementationscanbegiven
forfunctionsinaclass.Theseareusefulwhencer-
tainfunctionscanbedefinedintermsofothersin
theclass.Adefaultisdefinedbygivingabody
tooneofthememberfunctions.Thecanonicalex-
ampleisEq,whichdefines/=(notequal)interms
of==.:
dataPoly=TriangleTwoDTwoDTwoD
instead,thePointtypemustbeused:
dataPoly=TrianglePointPointPoint
TypeandConstructorNames Typeandcon-
structornamescanbethesame,becausetheywill
neverbeusedinaplacethatwouldcauseconfu-
sion.Forexample:
classEqawhere
(==)::a->a->Bool
(/=)::a->a->Bool
(/=)ab=not(a==b)
dataUser=UserString|AdminString
Recursivedefinitionscanbecreated,butan
instancedeclarationmustalwaysimplementat
leastoneclassmember.
whichdeclaresatypenamedUserwithtwocon-
structors,UserandAdmin.Usingthistypeina
functionmakesthedifferenceclear:
c2009JustinBailey. 3
355476662.002.png 355476662.003.png
 
whatUser(User_)="normaluser."
whatUser(Admin_)="adminuser."
Multipleconstructors(ofthesametype)canuse
thesameaccessorfunctionforvaluesofthesame
type,butthatcanbedangerousiftheaccessoris
notusedbyallconstructors.Considerthisrather
contrivedexample:
Becausesevenoftheseoperationsaresocom-
mon,Haskellprovidesthederivingkeyword
whichwillautomaticallyimplementthetypeclass
ontheassociatedtype.Thesevensupportedtype-
classesare:Eq,Read,Show,Ord,Enum,Ix,and
Bounded.
Twoformsofderivingarepossible.Thefirst
isusedwhenatypeonlyderivesoneclass:
Someliteraturereferstothispracticeastypepun-
ning.
TypeVariables Declaringso-calledpolymorphic
datatypesisaseasyasaddingtypevariablesin
thedeclaration:
dataCon=Con{conValue::String}
|Uncon{conValue::String}
|Noncon
dataSlot1a=Slot1a|Empty1
whichConcon="convalueis"++
conValuecon
dataPriority=Low|Medium|High
derivingShow
ThisdeclaresatypeSlot1withtwoconstructors,
Slot1andEmpty1.TheSlot1constructorcantake
anargumentofanytype,whichisrepresentedby
thetypevariableaabove.
Wecanalsomixtypevariablesandspecific
typesinconstructors:
IfwhichConiscalledwithaNonconvalue,arun-
timeerrorwilloccur.
Finally,asexplainedelsewhere,thesenames
canbeusedforpatternmatching,argumentcap-
tureand“updating.”
Thesecondisusedwhenmultipleclassesarede-
rived:
dataAlarm=Soft|Loud|Deafening
deriving(Read,Show)
dataSlot2a=Slot2aInt|Empty2
ClassConstraints Datatypescanbedeclared
withclassconstraintsonthetypevariables,but
thispracticeisgenerallydiscouraged.Itisgener-
allybettertohidethe“raw”dataconstructorsus-
ingthemodulesystemandinsteadexport“smart”
constructorswhichapplyappropriateconstraints.
Inanycase,thesyntaxusedis:
Above,theSlot2constructorcantakeavalueof
anytypeandanIntvalue.
Itisasyntaxerrortospecifyderivingforany
otherclassesbesidesthesixgivenabove.
RecordSyntax Constructorargumentscanbe
declaredeitherpositionally,asabove,orusing
recordsyntax,whichgivesanametoeachargu-
ment.Forexample,herewedeclareaContact
typewithnamesforappropriatearguments:
Deriving
data(Numa)=>SomeNumbera=Twoaa
|Threeaaa
Seethesectionon deriving underthedatakey-
wordonpage 4 .
dataContact=Contact{ctName::String
,ctEmail::String
,ctPhone::String}
ThisdeclaresatypeSomeNumberwhichhasone
typevariableargument.Validtypesarethosein
theNumclass.
Do
Thesenamesarereferredtoasselectororacces-
sorfunctionsandarejustthat,functions.They
muststartwithalowercaseletterorunderscore
andcannothavethesamenameasanotherfunc-
tioninscope.Thusthe“ct”prefixoneachabove.
Deriving Manytypeshavecommonoperations
whicharetedioustodefineyetnecessary,suchas
theabilitytoconverttoandfromstrings,compare
forequality,ororderinasequence.Thesecapa-
bilitiesaredefinedastypeclassesinHaskell.
Thedokeywordindicatesthatthecodetofollow
willbeinamonadiccontext.Statementsaresepa-
ratedbynewlines,assignmentisindicatedby<-,
andaletformisintroducewhichdoesnotre-
quiretheinkeyword.
c2009JustinBailey. 4
355476662.004.png 355476662.005.png
 
IfandIO ifcanbetrickywhenusedwith
IO.Conceptuallyitisnodifferentfromanif
inanyothercontext,butintuitivelyitishardto
develop.ConsiderthefunctiondoesFileExists
fromSystem.Directory:
letresult=
ifexists
then1
else0
returnresult
file->do
f<-readFilefile
putStrLn("Thefileis"++
show(lengthf)
++"byteslong.")
doesFileExist::FilePath->IOBool
Again,noticewherereturnis.Wedon’tputitin
theletstatement.Insteadweuseitonceatthe
endofthefunction.
Analternativesyntaxusessemi-colonsandbraces.
Adoisstillrequired,butindentionisunnecessary.
Thiscodeshowsacaseexample,buttheprinciple
appliestoifaswell:
Theifstatementhasthis“signature”:
if-then-else::Bool->a->a->a
Thatis,ittakesaBoolvalueandevaluatestosome
othervaluebasedonthecondition.Fromthetype
signaturesitisclearthatdoesFileExistcannotbe
useddirectlybyif:
Multiple do ’s Whenusingdowithiforcase,
anotherdoisrequiredifeitherbranchhasmulti-
plestatements.Anexamplewithif:
countBytes3=
do
putStrLn"Enterafilename."
args<-getLine
caseargsof
[]->putStrLn"Noargsgiven."
file->do{f<-readFilefile;
putStrLn("Thefileis"++
show(lengthf)
++"byteslong.");}
countBytes1f=
do
wrongfileName=
ifdoesFileExistfileName
then...
else...
putStrLn"Enterafilename."
args<-getLine
iflengthargs==0
--no’do’.
thenputStrLn"Nofilenamegiven."
else
--multiplestatementsrequire
--anew’do’.
do
Thatis,doesFileExistresultsinanIOBool
value,whileifwantsaBoolvalue.Instead,the
correctvaluemustbe“extracted”byrunningthe
IOaction:
Export
Seethesectionon module onpage 6 .
right1fileName=do
exists<-doesFileExistfileName
ifexists
thenreturn1
elsereturn0
f<-readFileargs
putStrLn("Thefileis"++
show(lengthf)
++"byteslong.")
If,Then,Else
Remember,ifalways“returns”avalue.Itisan
expression,notjustacontrolflowstatement.This
functiontestsifthestringgivenstartswithalower
caseletterand,ifso,convertsittouppercase:
Noticetheuseofreturn.Becausedoputsus“in-
side”theIOmonad,wecan’t“getout”except
throughreturn.Notethatwedon’thavetouse
ifinlinehere—wecanalsouselettoevaluate
theconditionandgetavaluefirst:
Andonewithcase:
countBytes2=
do
--Usepattern-matchingto
--getfirstcharacter
sentenceCase(s:rest)=
ifisLowers
thentoUppers:rest
elses:rest
putStrLn"Enterafilename."
args<-getLine
caseargsof
[]->putStrLn"Noargsgiven."
right2fileName=do
exists<-doesFileExistfileName
c2009JustinBailey. 5
355476662.006.png 355476662.007.png
 
Zgłoś jeśli naruszono regulamin