HaskellScripts YanHuang [email protected] LastQuiz Objectives • WritingHaskellprogramsin“.hs”files • NotesomedifferencesbetweenprogramstypedintoGHCi and programswritteninscriptfiles • OperatorPrecedence • OperatorAssociativity HaskellScripts • Aswellasthefunctionsinthestandardlibrary,youcanalsodefine yourownfunctions; • Newfunctionsaredefinedwithinascript,atextfilecomprisinga sequenceofdefinitions; • Byconvention,Haskellscriptsusuallyhavea.hs suffixontheir filename. MyFirstScript WhendevelopingaHaskellscript,itisusefultokeep twowindowsopen,onerunninganeditorforthe script,andtheotherrunningGHCi. Startaneditor,typeinthefollowingtwofunction definitions,andsavethescriptastest.hs: double x = x + x quadruple x = double (double x) Leavingtheeditoropen,inanotherwindowstartup GHCi withthenewscript: $ ghci test.hs Nowboththestandardlibraryandthefiletest.hs are loaded,andfunctionsfrombothcanbeused: > quadruple 10 40 > take (double 2) [1,2,3,4,5,6] [1,2,3,4] LeavingGHCi open,returntotheeditor,addthe followingtwodefinitions,andsave: factorial n = product [1..n] average ns = sum ns `div` length ns Note: z div isenclosedinback quotes,notforward; z x `f` y isjustsyntacticsugar forf x y. GHCi doesnotautomaticallydetectthatthescripthas beenchanged,soareload commandmustbeexecuted beforethenewdefinitionscanbeused: > :reload Reading file "test.hs" > factorial 10 3628800 > average [1,2,3,4,5] 3 UsefulGHCiCommands Command Meaning :load name :reload :type expr :? :quit load script name reload current script show type of expr show all commands quit GHCi :set editor name :edit name :edit set editor to name edit script name edit current script NamingRequirementsandConventions • Functionandargumentnamesmustbeginwitha lower-caseletter.Forexample: myFun fun1 arg_2 x’ Byconvention,listargumentsusuallyhaveanssuffix ontheirname.Forexample: xs ns nss TheLayoutRule Inasequenceofdefinitions,eachdefinitionmustbegin inpreciselythesamecolumn: a = 10 b = 20 c = 30 a = 10 b = 20 c = 30 a = 10 b = 20 c = 30 Thelayoutruleavoidstheneedforexplicitsyntaxto indicatethegroupingofdefinitions. a = b + c where b = 1 c = 2 d = a * 2 implicitgrouping means {a = b + c where {b = 1; c = 2} d = a * 2} explicitgrouping In script: In GHCi: a = 1 let a = 1 Operators Prelude λ: 3+5 Prelude λ: mod 3 5 8 3 Prelude λ: (+) 3 5 Prelude λ: 3 `mod` 5 8 3 Prelude λ: 3 / 5 Prelude λ: 2 `elem` [1,2,3] 0.6 True Prelude λ: (/) 3 5 Prelude λ: elem 2 [1,2,3] 0.6 True • Operatorsareinessence functions. • Operatorswhoseidentifiers consistofsymbolsareby defaultinfix.Surroundthem withparentheses touseas prefixoperators. • Operatorswithlettersintheir identifiersareprefix by default.Placetheminbackquotestouseasinfix operators. Prelude λ: :info + OperatorPrecedence 3+5∗2 class Num a where (+) :: a -> a -> a ... -- Defined in ‘GHC.Num’ infixl 6 + Prelude λ: :info * class Num a where ... “∗”hashigherprecedencethan“+” (*) :: a -> a -> a ... -- Defined in ‘GHC.Num’ infixl 7 * OperatorPrecedence + 3 5∗2 • Prefixform(+)istreatedasnormalfunction(precedenceescalatedto thatoffunctionapplications,whichishigherthan‘*’) • Infix+isprocessedasnormalbinaryoperators PrecedenceandAssociativityofSelectedOperators Left-associative 9 Non-associative !! Right-associative . 8 ^, ^^, ** 7 *, /, `div` 6 +, -, 5 :, ++ ==, /=, >, >=, <, <= `elem`, `notElem` 4 3 && 2 || 1 0 >>, >>= $, $!, `seq` • Functionapplicationsareoflevel10precedence. • Anyoperatorlackingafixitydeclarationisassumedtobe infixl 9. !! *Main λ: :type (!!) (!!) :: [a] -> Int -> a . *Main λ: :type (.) (.) :: (b -> c) -> (a -> b) -> a -> c ^,^^,** *Main λ: :type (^) (^) :: (Integral b, Num a) => a -> b -> a *Main λ: :type (^^) (^^) :: (Fractional a, Integral b) => a -> b -> a *Main λ: :type (**) (**) :: Floating a => a -> a -> a *, /, `div` *Main λ: :type (*) (*) :: Num a => a -> a -> a *Main λ: :type (/) (/) :: Fractional a => a -> a -> a *Main λ: :type div div :: Integral a => a -> a -> a +,- :,++ *Main λ: :type (:) (:) :: a -> [a] -> [a] *Main λ: :type (++) (++) :: [a] -> [a] -> [a] ==,/=,>,>=,<,<= `elem`,`notElem` *Main λ: :type elem elem :: (Eq a, Foldable t) => a -> t a -> Bool *Main λ: :type notElem notElem :: (Eq a, Foldable t) => a -> t a -> Bool && *Main λ: :type (&&) (&&) :: Bool -> Bool -> Bool || >>, >>= *Main λ: :t (>>) (>>) :: Monad m => m a -> m b -> m b *Main λ: :t (>>=) (>>=) :: Monad m => m a -> (a -> m b) -> m b $, $!,`seq` *Main λ: :info ($) ($) :: (a -> b) -> a -> b -- Defined in ‘GHC.Base’ infixr 0 $ *Main λ: :info ($!) ($!) :: (a -> b) -> a -> b -- Defined in ‘GHC.Base’ infixr 0 $! *Main λ: :info seq seq :: a -> b -> b infixr 0 `seq` -- Defined in ‘GHC.Prim’ Non-AssociativeOperators ==,/=,>,>=,<,<= `elem`,`notElem` Prelude λ: True == False False Prelude λ: True == False == False <interactive>:551:1: Precedence parsing error cannot mix ‘==’ [infix 4] and ‘==’ [infix 4] in the same infix expression OperatorAssociativity • Associatetotheleft 1+2+35-4-318/9/1 OperatorAssociativity • Associatetotheright 5^3^2 Prelude λ: :info ^ (^) :: (Num a, Integral b) => a -> b -> a -- Defined in ‘GHC.Real’ infixr 8 ^ 1:2:3:[] Prelude λ: :info : data [] a = ... | a : [a] infixr 5 : -- Defined in ‘GHC.Types’ OperatorPrecedenceandAssociativity f gx ≢fgx f gx ≡f$gx CustomizingPrecedenceandAssociativity multThenInc :: Int -> Int -> Int multThenInc x y = x * y + 1 infix 3 @@ (@@) = multThenInc @@operatorhasprecedencelevel3,non-associative. @@isabinaryfunctiononInt asspecifiedbymultThenInc. OperatorPrecedenceandAssociativity 5^3-1^2:2^3*3`div`2:3+5:3+2^3`div`2+3:[] Exercises (1) Fixthesyntaxerrorsintheprogrambelow,and testyoursolutionusingGHCi. N = a ’div’ length xs where a = 10 xs = [1,2,3,4,5] (2) Showhowthelibraryfunctionlast thatselects thelastelementofalistcanbedefinedusingthe functionsintroducedinthislecture. (3) Canyouthinkofanotherpossibledefinition? (4) Similarly,showhowthelibraryfunctioninit thatremovesthelastelementfromalistcanbe defined(possiblyintwodifferentways). (5) Whatdoes1 @@ 2 @@ 3 + 4 evaluatetounder thefollowingthreedefinitions?Explain. multThenInc :: Int -> Int -> Int multThenInc x y = x * y + 1 multThenInc :: Int -> Int -> Int multThenInc x y = x * y + 1 multThenInc :: Int -> Int -> Int multThenInc x y = x * y + 1 infixl 3 @@ (@@) = multThenInc infixl 7 @@ (@@) = multThenInc infix 5 @@ (@@) = multThenInc (6) Whatdo1 @@ 2 @@ 3, 1 == 2 == 2, 3 @@ 5 == 1 evaluateto,respectively?Explain.
© Copyright 2026 Paperzz