Presentation is loading. Please wait.

Presentation is loading. Please wait.

An introduction to functional programming using Haskell CENG242 –Recitation 1.

Similar presentations


Presentation on theme: "An introduction to functional programming using Haskell CENG242 –Recitation 1."— Presentation transcript:

1 An introduction to functional programming using Haskell CENG242 –Recitation 1

2 Introduction: Haskell  The most popular purely functional, lazy programming language  “Functional programming language”:  a program is a collection of mathematical functions  “Purely functional”:  all variables refer to immutable, persistent values  that is, new values can be created, but existing ones cannot be modified  no destructive updates  “Lazy”:  expressions are evaluated “by need”

3 HUGS  A well-known Haskell system  An interpreter; test and debug programs in an interactive environment  Can be downloaded from its webpage  http://haskell.org/hugs  Prelude module is always loaded and contains the standard definitions ( (:) operator, (+), (*), fst, etc.)  Hugs will not run without the prelude file.  Some helpful commands:  :?, :quit, :type / :t, :load / :l, :reload / :r, :main, etc.

4 HUGS  Using the HUGS command prompt, you can evaluate expressions; however you cannot make definitions.  You can define new variables and functions in files and load them from Haskell prompt. Hugs> take 3 a where a = [1, 2, 3, 4, 5, 6, 7] [1,2,3] Hugs> b = take 3 a where a = [1, 2, 3, 4, 5, 6, 7] ERROR - Syntax error in input (unexpected `=') Hugs> take 3 a where a = [1, 2, 3, 4, 5, 6, 7] [1,2,3] Hugs> b = take 3 a where a = [1, 2, 3, 4, 5, 6, 7] ERROR - Syntax error in input (unexpected `=') --sample.hs module Sample where b = take 3 a where a = [1, 2, 3, 4, 5, 6, 7] --sample.hs module Sample where b = take 3 a where a = [1, 2, 3, 4, 5, 6, 7] Hugs>:load sample Hugs>b [1,2,3] Hugs>:load sample Hugs>b [1,2,3]

5 Haskell  Value and type concepts are essential in grasping the main idea of Haskell programming language.  All computations are done via the evaluation of expressions (syntactic terms) to yield values (abstract entities that we regard as answers).  Every value has an associated type. ( :: can be read as ‘has type’) a =1 b = [1, 2, 3] a =1 b = [1, 2, 3] a :: Integer b :: [Integer] a :: Integer b :: [Integer]

6 Cont’d…  Haskell is case-sensitive  Type names and constructor names begin with an upper-case letter  e.g Expr or Rectangle  Value names begin with lower-case letter  e.g. x or intTemp  Function names begin with lower-case letter (functions are values too)  e.g. square or filter

7 Types  Basic types: Integer, String, Float, Double, Char, …  [X] : a list of x values  [1,2,3,4]  []  Lists are homogeneous (elements are of the same type)  X -> Y: a function from X value to Y value  (X, Y, Z) : a tuple of a X value, a Y value and a Z value  Pair: (4, „a ‟ )  Triple: (“hi”, [1,2], 6)  Elements do not need to have the same types  …

8 Strong Typing  Every expression has a type which can be deduced at compile-time.  The main advantage of statically typed languages is well- known: All type errors are detected at compile-time. len :: [Integer] -> Integer len [] = 0 len (x:xs) = len(xs) + 1 number :: [Integer] number = [7, 19, 13] n :: Integer n = len numbers len :: [Integer] -> Integer len [] = 0 len (x:xs) = len(xs) + 1 number :: [Integer] number = [7, 19, 13] n :: Integer n = len numbers

9 Type Inference  In Haskell, writing type annotations is optional  Use them to express the intended meaning of your functions  Omit them if the meaning is “obvious”  When omitted, Haskell finds the type for you!  …in fact, the best possible type  (also called, the principle type)

10 Values and Types  All Haskell values are "first-class"---they may be passed as arguments to functions, returned as results, placed in data structures, etc.  Functions are values too! Hence you can pass functions as arguments to other functions (called higher order functions)  Haskell types, on the other hand, are not first-class. Types in a sense describe values, and the association of a value with its type is called a typing.  The static type system ensures that Haskell programs are type safe.

11 Some basic functions  length, tail, head, null  ++, ==, /=  fst, snd  sqrt  show, read

12 Defining Functions square x = x * x  Here we’re defining a function square that takes one argument, which we call x. Then we say that the value of square x is equal to x*x  Functions in Haskell are normally defined by a series of equations (every line gives an equation in the following code): func 0 = 1 func 1 = 5 func 2 = 2 func _ = -1 –Underscore (_) means ‘don’t care’

13 Defining Functions  Consider the following function:  The left-hand sides of the equations contain patterns such as 0 and _. In a function application these patterns are matched against actual parameters.  If the match succeeds, the right-hand side is evaluated and returned as the result of the application.  Note that a stronger match is always preferred over a weaker match, otherwise the above function would always yield 0. unitImpulse :: Integer -> Integer unitImpulse 0 = 1 unitImpulse _ = 0 unitImpulse :: Integer -> Integer unitImpulse 0 = 1 unitImpulse _ = 0

14 Defining Functions  Consider the previous example  Haskell can match lists as the first element and remaining portion of list.  It’s also possible to match the last element and the rest len :: [Integer] -> Integer len [] = 0 len (x:xs) = len(xs) + 1 len :: [Integer] -> Integer len [] = 0 len (x:xs) = len(xs) + 1 len :: [Integer] -> Integer len [] = 0 len (xs:x) = len(xs) + 1 –Note the difference len :: [Integer] -> Integer len [] = 0 len (xs:x) = len(xs) + 1 –Note the difference

15 If-then-else expressions  if e 1 then e 2 else e 3 signum x = if x < 0 then -1 else if x > 0 then 1 else 0  You must have both a then and an else clause

16 Case expressions  case expressions are used when there are multiple values that you want to check against casefunc x = case x of 0 -> 1 1 -> 5 2 -> 2 _ ->-1

17 Guards  Enable you to allow piecewise function definitions to be taken according to arbitrary Boolean expressions.  e.g. compare x y | x < y = “The first is less” | x > y = “The second is less” | otherwise= “They are equal” or; compare2 x y | x < y = "The first is less“ | x > y = "The second is less" compare2 _ _ = "They are equal"

18 Cont’d…  More complicated functions can be built from simpler functions using function composition  Function composition: taking the result of one function and use it as an argument  e.g. square (sqrt 2)  Here, parenthesis is necessary, otherwise the interpreter would think that you try to get the value of “square sqrt”  Another way to express function composition is using the (.) function  e.g. (square.sqrt) 2

19 Recursion  No loops in Haskell  Uses recursion  Divide and conquer!  e.g. exponential a 0 = 1 exponential a b = a * exponential a (b-1) lenFunc [] = 0 lenFunc (x:xs) = 1 + lenFunc xs

20 Cont’d…  e.g. filterFunc func [] = [] filterFunc func (x:xs) = if func x then x : filterFunc func xs else filterFunc func xs  e.g. reverse [] = [] reverse (x:xs) = reverse xs ++ [x]

21 Type definitions  Red, Green, Blue, Rectangle, and Circle are called constructors data Color = Red | Green | Blue f Red = 1 f Blue = 2 f _ = 3 data Color = Red | Green | Blue f Red = 1 f Blue = 2 f _ = 3 data Shape = Rectangle Float Float | Circle Float Area (Rectangle x y) = x * y Area (Circle r) = pi * r * r data Shape = Rectangle Float Float | Circle Float Area (Rectangle x y) = x * y Area (Circle r) = pi * r * r

22 Cont’d…  data keyword provides the capability to define new types.  Both Bool and Color are examples of enumerated types, since they consist of a finite number of nullary data constructors. data Color = Red | Green | Blue data Bool = True | False data Color = Red | Green | Blue data Bool = True | False

23 Cont’d…  You should distinguish between applying a data constructor to yield a value, and applying a type constructor to yield a type.  The former happens at run-time and is how we compute things in Haskell, whereas the latter happens at compile- time and is part of the type system's process of ensuring type safety. --Point is the Cartesian product of two values of same type --Note x which is lower case. It’s possible to express a new --type, such as Point of Integer (Point Integer) or Point of Float data Point x = Pt x x p :: Point Integer p = Pt 2 3 --Point is the Cartesian product of two values of same type --Note x which is lower case. It’s possible to express a new --type, such as Point of Integer (Point Integer) or Point of Float data Point x = Pt x x p :: Point Integer p = Pt 2 3

24 Cont’d…  It’s crucial to understand the distinction between data constructors and type constructors.  Identifiers such as ‘x' above are called type variables, and are uncapitalized to distinguish them from specific types such as Int. --Point is a type constructor, whereas Pt is a data constructor data Point x = Pt x x --For type enforcement, we use the type constructor --In equations, we use data constructors since we try to match --values sumCoord :: Point Integer -> Integer sumCoord (Pt a b) = a + b p :: Point Integer p = Pt 2 3 s = sumCoord p --Point is a type constructor, whereas Pt is a data constructor data Point x = Pt x x --For type enforcement, we use the type constructor --In equations, we use data constructors since we try to match --values sumCoord :: Point Integer -> Integer sumCoord (Pt a b) = a + b p :: Point Integer p = Pt 2 3 s = sumCoord p

25 Type Synonyms  For convenience, Haskell provides a way to define type synonyms; i.e. names for commonly used types. type String = [Char] type AssocList a b = [(a,b)] (Polymorphism)  String is simply a list of characters

26 Examples  data List a = Nil | Cons a (List a) listLength Nil = 0 listLength (Cons x xs) = 1 + listLength xs  data BinaryTree a = Leaf a | Branch (BinaryTree a) a (Binary Tree a) treeSize (Leaf x) = 1 treeSize (Branch left x right) = 1 + treeSize left + treeSize right

27 Comments --Computes the length of a list len :: [Integer] -> Integer len [] = 0 len (x:xs) = len(xs) + 1 {- number :: [Integer] number = [7, 19, 13] n :: Integer n = len numbers -} --Computes the length of a list len :: [Integer] -> Integer len [] = 0 len (x:xs) = len(xs) + 1 {- number :: [Integer] number = [7, 19, 13] n :: Integer n = len numbers -}

28  Any questions?


Download ppt "An introduction to functional programming using Haskell CENG242 –Recitation 1."

Similar presentations


Ads by Google