Download presentation
Presentation is loading. Please wait.
1
BB1756: Software Development Functional Programming in Haskell 2010/2011 Dan Russell Email: djrussell@kingston.ac.uk WWW: http://staffnet.kingston.ac.uk/~ku02309
2
BB1756: SWD2 Administration Materials for the course, including handouts, the module guide, and the lab session worksheets, will be on my SWD web page at: http://staffnet.king.ac.uk/~ku02309/courses/swd1011.html This page can be accessed directly from StudySpace. Exercise Classes: using the Hugs interpreter.
3
BB1756: SWD3 Software Development A.K.A. The Development of Software A.K.A.The analysis of a problem and the design (using a choice of media) and implementation (using a programming language) of a solution to the problem.
4
BB1756: SWD4 Programming Paradigms Various including: Imperative/Procedural, Object-Oriented and Functional Each paradigm is populated with a collection of programming languages and support tools such as analysis and design methodologies (ADMs).
5
BB1756: SWD5 Programming Languages Imperative/Procedural: Fortran, Cobol, Pascal, Basic and C Object-Oriented: C++, Java and C# (plus JavaScript which is a Web scripting language that you will use at Level 5) Functional: Miranda, Scheme, ML and Haskell
6
BB1756: SWD6 Functional Programming Programming with functions in contrast to Programming with objects and also in contrast to Programming with procedures
7
BB1756: SWD7 Functional Programming The programming language we use on this course is Haskell 98. See http://www.haskell.org/ There are various implementations of the language. The one we will use on this course is Hugs 98. Runs on: Windows, Unix, Linux and MacOS. See http://www.haskell.org/hugs/
8
BB1756: SWD8 FORMALITY Every programming language is a formal language which has to be adhered to for a program to work. That is, it will have a set of rules regarding things like: -- what is an acceptable name; -- what is acceptable layout; -- whether it is case-sensitive or not; and so on…
9
BB1756: SWD9 FORMALITY Rule 1: Every function name MUST begin with a lower case letter. Rule 2: No spaces are allowed in any name.
10
BB1756: SWD10 Your First Problem Define a function which doubles its input. The analysis could include some sample input/output values to: i. make sure that you understand the problem; ii. get an idea of the number and kind of input(s) required; iii. get an idea of the kind of output required. Note: These are non-programming issues. If you don’t understand the problem there is no way you can find a solution.
11
BB1756: SWD11 Your First Problem Define a function which doubles its input. InputOutput 1 7 43 -9 A textual description of the function based on the above is often useful. Multiply the input value by 2. So how many input(s) are required, what are they, and what kind of output is required?
12
BB1756: SWD12 Your First Problem So when designing the solution we need a function which requires a single number input, and returns a number as output. Part of the design process is deciding on a name for the function and a name for each input value. The function name should suggest what the function does. The input name should be short but should also give an indication of what the input is, if possible.
13
BB1756: SWD13 Your First Problem Which of the following combinations of function and input names is sensible? Function NameInput Name f x carrot k square t doubledouble double n d n So now all we have to do is implement the solution!
14
BB1756: SWD14 Your First Haskell Program module Program1 where -- This is a comment. A module hosts a collection -- of definitions. A module name begins with an -- upper case (CAPITAL) letter. double n = 2 * n -- Another comment. The function called -- double returns double the input value. -- The input value is called n.
15
BB1756: SWD15 Your First Haskell Program Lets use the program that we have just written. Main> :l Program1 Reading file "Program1.hs": Hugs session for: C:\Program Files\Hugs98\lib\Prelude.hs Program1.hs Main> double 3 6 Main> double 27 54 Main> double 1312 2624 Main> double 43.2 86.4 This is how you load the program This confirms that the program has been found and is OK. Examples of using a function defined in the program. Note: the function ALWAYS appears to the left of its argument(s).
16
BB1756: SWD16 Your First Haskell Program Lets try to use a program that we have not yet written. Main> :l Program2 Reading file "Program2": ERROR "Program2" - Unable to open file "Program2" Main> :l Program1 Reading file "Program1.hs": Hugs session for: C:\Program Files\Hugs98\lib\Prelude.hs Program1.hs Main> duoble 7654 ERROR - Undefined variable "duoble“ Main> This indicates that the program does not exist. Now Program1 has to be loaded again. This error message is received when the function cannot be found.
17
BB1756: SWD17 Your First Haskell Program Lets continue to use the program. Main> double Main> double 'B' ERROR - Illegal Haskell 98 class constraint in inferred type *** Expression : double 'B' *** Type : Num Char => Char This indicates that the function is being applied to the wrong type of thing.
18
BB1756: SWD18 FORMALITY Rule 3: When using a function it must always appear to the left of the thing(s) to which it is applied (the argument(s)). Rule 4: There must always be at least one space between a function and its argument(s).
19
BB1756: SWD19 Your Second Problem Define a function which returns the maximum of two integers. The analysis could include some sample input/output values to: i. make sure that you understand the problem; ii. get an idea of the number and kind of input(s) required; iii. get an idea of the kind of output required. Note: These are non-programming issues. If you don’t understand the problem there is no way you can find a solution.
20
BB1756: SWD20 Your Second Problem Define a function which returns the maximum of two integers. Input 1 Input 2Output 1 5 7 3 43 43 - 9 0 A textual description of the function based on the above is often useful. If the first input is less than the second then the second is returned. If the first input is greater than or equal to the second then the first is returned.
21
BB1756: SWD21 Your Second Problem So when designing the solution we need a function which requires two integer (whole number) inputs, and returns an integer as output. Part of the design process is deciding on a name for the function and a name for each input value. The function name should suggest what the function does. The input names should be short but should also give an indication of what the input is, if possible.
22
BB1756: SWD22 Your Second Problem Which of the following combinations of function and input names is sensible? Function NameInput 1 Name Input 2 Name f x y carrot k t double m n maxOf2 i i maxOf2 i j maximum x y So now all we have to do is implement the solution!
23
BB1756: SWD23 Your Second Haskell Program module Program2 where -- The function maxOf2 takes two integers -- and returns the maximum maxOf2 i j = if i < j then j else i -- Note how the definition mimics -- the description. If the first input is less than the second then the second is returned. If the first input is greater than or equal to the second then the first is returned.
24
BB1756: SWD24 So What Does One Do? Analyse: Investigate the problem, identifying the essential features. Design: Develop an implementable solution using a chosen medium (i.e. text, pseudocode, actual code or graphical) Implement: Write code in your chosen programming language that faithfully implements the design.
25
BB1756: SWD25 Essential Building Blocks of Functional Programming #1 FUNCTIONS A function is something which given a particular input value(s) returns one particular output value. We implement software in Haskell (Hugs) by defining a collection of functions.
26
BB1756: SWD26 Which of the following are functions? 1.daysInMonth 2.countryVisitedThisYear 3. capitalCityOf 4. sittingNextTo
27
BB1756: SWD27 Some Functions... -- addOne simply adds one to the input value addOne n = n + 1 -- square uses the `to the power of’ operator ^ square m = m ^ 2 -- always7 ignores the input value and returns 7 always7 k = 7 -- isGreaterThan10 tests whether the input -- number is greater than 10 isGreaterThan10 p = p > 10
28
BB1756: SWD28 Essential Building Blocks of Functional Programming #2 TYPES A type is a collection of values (such as integers and characters) which are grouped together because they are the same sort of thing. They are used as part of the design process, and as a guide to the user of a function as to what can be input and what will be output.
29
BB1756: SWD29 Some Functions (now with types)... addOne n = n + 1 square m = m ^ 2 always7 k = 7 isGreaterThan10 p = p > 10
30
BB1756: SWD30 Some Functions (now with types)... Function Name Input Type Output Type addOne :: Int -> Int addOne n = n + 1 square m = m ^ 2 always7 k = 7 isGreaterThan10 p = p > 10
31
BB1756: SWD31 Some Functions (now with types)... Function Name Input Type Output Type addOne :: Int -> Int addOne n = n + 1 square :: Float -> Float square m = m ^ 2 always7 k = 7 isGreaterThan10 p = p > 10
32
BB1756: SWD32 Some Functions (now with types)... Function Name Input Type Output Type addOne :: Int -> Int addOne n = n + 1 square :: Float -> Float square m = m ^ 2 always7 :: any -> Int always7 k = 7 isGreaterThan10 p = p > 10
33
BB1756: SWD33 Some Functions (now with types)... Function Name Input Type Output Type addOne :: Int -> Int addOne n = n + 1 square :: Float -> Float square m = m ^ 2 always7 :: any -> Int always7 k = 7 isGreaterThan10 :: Int -> Bool isGreaterThan10 p = p > 10
34
BB1756: SWD34 Why You Should Love Types! The first reason why you should love types is that: they provide a clear guide in development. That is, after doing some analysis you can discover the required input type(s) and output type. Thus you know exactly what the function can be applied to and what it can return. It is often the case that one specifies the type of a function well in advance of defining the function. This is so that other developers know about the existence of the function and about how it may be used. Note: Most popular programming languages are typed (have types). Thus these arguments apply for Java, C#, C++ and so on.
35
BB1756: SWD35 Why You Should Love Types! For example: aFun :: Int -> Int aFun takes an Int and returns an Int
36
BB1756: SWD36 Why You Should Love Types! For example: aFun :: Int -> Int bFun :: String -> Bool aFun takes an Int and returns an Int bFun takes a String and returns a Bool
37
BB1756: SWD37 Why You Should Love Types! For example: aFun :: Int -> Int bFun :: String -> Bool cFun :: Char -> Char -> String aFun takes an Int and returns an Int bFun takes a String and returns a Bool cFun takes tw o Char s and returns a String
38
BB1756: SWD38 Why You Should Love Types! For example: aFun :: Int -> Int bFun :: String -> Bool cFun :: Char -> Char -> String dFun :: (Float,Float) -> String aFun takes an Int and returns an Int bFun takes a String and returns a Bool cFun takes two Chars and returns a String dFun takes a pair of Floats and returns a String
39
BB1756: SWD39 Why You Should Love Types! The second reason why you should love types is that: anybody who wants to use the functions in the future knows what they require as input and return as output. Often all that one wants to know about a function that one wants to reuse is the type(s) of its input, the type of its output, and what the function does. That is, one doesn’t need to know how the function does what it does.
40
BB1756: SWD40 Why You Should Love Types! For example: fFun str = addOne (length str)
41
BB1756: SWD41 Why You Should Love Types! For example: fFun :: String -> Int fFun str = addOne (length str) The input to fFun is a String and the output is an Int. Since length can be applied to a String and returns its length as an Int, and addOne is applied to an Int, this is OK. We do not care how length is defined!
42
BB1756: SWD42 Why You Should Love Types! For example: gFun s i = i == length s
43
BB1756: SWD43 Why You Should Love Types! For example: gFun :: String -> Int -> Bool gFun s i = i == length s The inputs to gFun is a String and an Int. The output is a Bool. length can be applied to a String and return an Int. == takes two values (of the same type) and returns a Bool. We do not care how length and == are defined!
44
BB1756: SWD44 Why You Should Love Types! The third reason why you should love types is that: they allow the compiler (e.g. Hugs) to spot errors in the function definition. That is, the input(s) and output of the function are specified by types and the definition needs to be consistent with this. Note: This is called a compile-time error.
45
BB1756: SWD45 Why You Should Love Types! For example: hFun :: String -> Int hFun x = x + 99
46
BB1756: SWD46 Why You Should Love Types! For example: hFun :: String -> Int hFun x = x + 99 The input to hFun is a String and the output is an Int. The definition tries to add a String to 99 which will result in a compile-time error.
47
BB1756: SWD47 Why You Should Love Types! For example: hFun :: String -> Int hFun x = x + 99 iFun :: (Char, Char) -> Bool iFun c1 c2 = c1 == c2 The input to hFun is a String and the output is an Int. The definition tries to add a String to 99 which will result in a compile-time error.
48
BB1756: SWD48 Why You Should Love Types! For example: hFun :: String -> Int hFun x = x + 99 iFun :: (Char, Char) -> Bool iFun c1 c2 = c1 == c2 The input to hFun is a String and the output is an Int. The definition tries to add a String to 99 which will result in a compile-time error. The input to iFun is a pair of Char s. The definition uses two Char s. This is not the same and thus a compile-time error!
49
BB1756: SWD49 Why You Should Love Types! For example: hFun :: String -> Int hFun x = x + 99 iFun :: (Char, Char) -> Bool iFun c1 c2 = c1 == c2 jFun :: String -> Int -> Bool jFun s i = if length s == i then “Same” else “Different” The input to hFun is a String and the output is an Int. The definition tries to add a String to 99 which will result in a compile-time error. The input to iFun is a pair of Char s. The definition uses two Char s. This is not the same and thus a compile-time error!
50
BB1756: SWD50 Why You Should Love Types! For example: hFun :: String -> Int hFun x = x + 99 iFun :: (Char, Char) -> Bool iFun c1 c2 = c1 == c2 jFun :: String -> Int -> Bool jFun s i = if length s == i then “Same” else “Different” The input to hFun is a String and the output is an Int. The definition tries to add a String to 99 which will result in a compile-time error. The input to iFun is a pair of Char s. The definition uses two Char s. This is not the same and thus a compile-time error! The input to jFun is a String and an Int. The output is a Bool. The output in the definition is a String. This clashes with the specification and thus is a compile-time error!
51
BB1756: SWD51 Why You Should Love Types! The fourth reason why you should love types is that: they allow errors to be identified when the function is actually used. That is, if one tries to apply a function to the incorrect input then the type specification will highlight this error. Note: This is called a runtime error.
52
BB1756: SWD52 Why You Should Love Types! For example: hugs:> length 7 hugs:> snd “Dan” True hugs:> double True
53
BB1756: SWD53 Why You Should Love Types! For example: hugs:> length 7 hugs:> snd “Dan” True hugs:> double True The input to length is a String. Here we are trying to apply it to an Int which results in a runtime error.
54
BB1756: SWD54 Why You Should Love Types! For example: hugs:> length 7 hugs:> snd “Dan” True hugs:> double True The input to length is a String. Here we are trying to apply it to an Int which results in a runtime error. The input to snd is a pair of values. Here we are trying to apply it to two values which results in a runtime error.
55
BB1756: SWD55 Why You Should Love Types! For example: hugs:> length 7 hugs:> snd “Dan” True hugs:> double True The input to length is a String. Here we are trying to apply it to an Int which results in a runtime error. The input to snd is a pair of values. Here we are trying to apply it to two values which results in a runtime error. The input to double is an Int. Here we are trying to apply it a Bool which is a runtime error.
56
BB1756: SWD56 Why You Should Love Types! The final reason why you should love types is that: without them all of the above benefits would disappear. That is, -- erroneous code would compile! -- one could apply functions to inappropriate inputs and something (unexpected) would happen! -- potential users of functions would have no idea how they should be used!
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.