Download An introduction to functional programming using Haskell

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Scala (programming language) wikipedia , lookup

Anonymous function wikipedia , lookup

Falcon (programming language) wikipedia , lookup

Curry–Howard correspondence wikipedia , lookup

Closure (computer programming) wikipedia , lookup

Currying wikipedia , lookup

Intuitionistic type theory wikipedia , lookup

C Sharp (programming language) wikipedia , lookup

Standard ML wikipedia , lookup

Transcript
An introduction to functional
programming using Haskell
CENG242 –Recitation 1
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”
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.
HUGS

Using the HUGS command prompt, you can evaluate
expressions; however you cannot make definitions.
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 `=')

You can define new variables and functions in files and
load them from Haskell prompt.
--sample.hs
module Sample where
b = take 3Hugs>:load
a where a sample
= [1, 2, 3, 4, 5, 6, 7]
Hugs>b
[1,2,3]
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).
a =1
b = [1, 2, 3]

Every value has an associated type. ( :: can be read as ‘has type’)
a :: Integer
b :: [Integer]
Cont’d…

Haskell is case-sensitive

Type names and constructor names begin with an upper-case
letter


Value names begin with lower-case letter


e.g Expr or Rectangle
e.g. x or intTemp
Function names begin with lower-case letter (functions are
values too)

e.g. square or filter
Types


Basic types: Integer, String, Float, Double, Char, …
[X] : a list of x values





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




[1,2,3,4]
[]
Lists are homogeneous (elements are of the same type)
Pair: (4, „a‟)
Triple: (“hi”, [1,2], 6)
Elements do not need to have the same types
…
Strong Typing
len :: [Integer] -> Integer
len [] = 0
len (x:xs) = len(xs) + 1
number :: [Integer]
number = [7, 19, 13]
n :: Integer
n = len numbers


Every expression has a type which can be deduced at
compile-time.
The main advantage of statically typed languages is wellknown: All type errors are detected at compile-time.
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)
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.
Some basic functions





length, tail, head, null
++, == , /=
fst, snd
sqrt
show, read
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’
Defining Functions

Consider the following function:
unitImpulse :: Integer -> Integer
unitImpulse 0 = 1
unitImpulse _ = 0



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.
Defining Functions

Consider the previous example
len :: [Integer] -> Integer
len [] = 0
len (x:xs) = len(xs) + 1


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 (xs:x) = len(xs) + 1 –Note the difference
If-then-else expressions

if e1 then e2 else e3
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
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
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"
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
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
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]
Type definitions
data Color = Red | Green | Blue
f Red = 1
f Blue = 2
f _ = 3data Shape = Rectangle Float Float
| Circle Float
Area (Rectangle x y) = x * y
Area (Circle r) = pi * r * r

Red, Green, Blue, Rectangle, and Circle are called
constructors
Cont’d…

data keyword provides the capability to define new types.
data Color = Red | Green | Blue
data Bool = True | False

Both Bool and Color are examples of enumerated types,
since they consist of a finite number of nullary data
constructors.
Cont’d…
--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


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 compiletime and is part of the type system's process of ensuring
type safety.
Cont’d…

It’s crucial to understand the distinction between data constructors
and type constructors.
--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

Identifiers such as ‘x' above are called type variables, and are
uncapitalized to distinguish them from specific types such as Int.
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
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
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
-}

Any questions?