z-functional programming in haskell

Upload: surangma-parashar

Post on 06-Apr-2018

239 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/3/2019 Z-Functional Programming in Haskell

    1/26

    Seminar Report On

    FUNCTIONAL PROGRAMMING IN HASKELL

    Submitted by

    SITHARA A

    In the partial fulfillment of requirements in degree of

    Master of Technology (M-Tech) in Computer & Information Science

    DEPARTMENT OF COMPUTER SCIENCE

    COCHIN UNIVERSITY OF SCIENCE AND TECHNOLOGY

    KOCHI-682022

    2008

  • 8/3/2019 Z-Functional Programming in Haskell

    2/26

    ACKNOWLEDGEMENT

    I thank God almighty for guiding me throughout the seminar. I would like to thank all those who

    have contributed to the completion of the seminar and helped me with valuable suggestions for

    improvement.

    I am extremely grateful to Prof. Dr. K Poulose Jacob, Director, Dept.of Computer Science , for

    providing me with best facilities and atmosphere for the creative work guidance and

    encouragement. I would like to thank my coordinator, Mr.G Santhosh Kumar, Lecturer, Dept. of

    computer Science , for all help and support extend to me. I thank all staff members of my college

    and friends for extending their cooperation during my seminar.

    Above all I would like to thank my parents without whose blessings; I would not have been able to

    accomplish my goal.

  • 8/3/2019 Z-Functional Programming in Haskell

    3/26

    ABSTRACT

    As software becomes more and more complex, it is more and more important to structure it well.

    Well-structured software is easy to write, easy to debug, and provides a collection of modules that

    can be re-used to reduce future programming costs. Conventional languages place conceptual limits

    on the way problems can be modularized. Functional languages push those limits back. Writing

    large software systems that work is difficult and expensive. Maintaining those systems is even more

    difficult and expensive. Functional programming languages, such as Haskell, can make it easier and

    cheaper.

    Haskell is an advanced purely functional programming language. The product of more than twenty

    years of cutting edge research, it allows rapid development of robust, concise, correct software. With

    strong support for integration with other languages, built-in concurrency and parallelism,

    debuggers, profilers, rich libraries and an active community, Haskell makes it easier to produce

    flexible, maintainable high-quality software.

    KEY WORDS: lambda calculus, pure, currying , lazy evaluation, higher order functions, Lolita,

    house, list comprehension, tail recursion, adhoc polymorphism.

    http://haskell.org/haskellwiki/Functional_programminghttp://www.cse.unsw.edu.au/~chak/haskell/ffi/http://haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelismhttp://hackage.haskell.org/packages/hackage.htmlhttp://www.cse.unsw.edu.au/~chak/haskell/ffi/http://haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelismhttp://hackage.haskell.org/packages/hackage.htmlhttp://haskell.org/haskellwiki/Functional_programming
  • 8/3/2019 Z-Functional Programming in Haskell

    4/26

    CONTENTS

    1. INTRODUCTION.........................................................................................................5

    2. FUNCTIONAL vs. IMPERATIVE PROGRAMMING...............................................6

    3. FEATURES OF HASKELL.........................................................................................7

    3.1 PURE...................................................................................................................7

    3.2 STRONGLY TYPED...........................................................................................7

    3.3 STATICALLY TYPED........................................................................................8

    3.4 FUNCTIONAL....................................................................................................8

    3.5 CURRYING.........................................................................................................10

    3.6 LIST COMPREHENSIONS................................................................................10

    3.7 LAZY EVALUATION.......................................................................................12

    3.8 RECURSION................................................................................................14

    3.9 HIGHER ORDER FUNCTIONS..................................................................15

    3.10 POLYMORPHISM.....................................................................................................16

    4.APPLICATION AREAS.....................................................................................................18

    4.1 NATURAL LANGUAGE INTERFACES.......................................................22

    4.2 PARALLEL PROGRAMMING.......................................................................23

    5. HASKELL IN PRACTICE........................................................................................24

    6. CONCLUSION...........................................................................................................25 7. REFERENCES............................................................................................................26

  • 8/3/2019 Z-Functional Programming in Haskell

    5/26

    1. INTRODUCTION

    Haskell is a computer programming language. In particular, it is a polymorphicallystatically typed,

    lazy, purely functional language, quite different from most other programming languages. The

    language is named for Haskell Brooks Curry, whose work in mathematical logic serves as a

    foundation for functional languages. Haskell is based on the lambda calculus; hence the lambda is

    used as logo. Haskell offers:

    Substantially increased programmer productivity.

    Shorter, clearer, and more maintainable code.

    Fewer errors, higher reliability.

    A smaller "semantic gap" between the programmer and the language.

    Shorter lead times.

    Haskell is a wide-spectrum language, suitable for a variety of applications. It is particularly suitable

    for programs which need to be highly modifiable and maintainable. Much of a software product's

    life is spent in specification, design and maintenance, and not in programming. Functional

    languages are superb for writing specifications which can actually be executed and hence tested and

    debugged. Such a specification then is the first prototype of the final program. Functional programs

    are also relatively easy to maintain, because the code is shorter, clearer, and the rigorous control of

    side effects eliminates a huge class of unforeseen interactions.

    http://www.haskell.org/haskellwiki/Polymorphismhttp://www.haskell.org/haskellwiki/Typinghttp://www.haskell.org/haskellwiki/Lazy_evaluationhttp://www.haskell.org/haskellwiki/Functional_programminghttp://www.haskell.org/haskellwiki/Haskell_Brooks_Curryhttp://www.haskell.org/haskellwiki/Lambda_calculushttp://www.haskell.org/haskellwiki/Polymorphismhttp://www.haskell.org/haskellwiki/Typinghttp://www.haskell.org/haskellwiki/Lazy_evaluationhttp://www.haskell.org/haskellwiki/Functional_programminghttp://www.haskell.org/haskellwiki/Haskell_Brooks_Curryhttp://www.haskell.org/haskellwiki/Lambda_calculus
  • 8/3/2019 Z-Functional Programming in Haskell

    6/26

    2. FUNCTIONAL vs. IMPERATIVE PROGRAMMING

    The functional programming paradigm was explicitly created to support a pure functional approach

    to problem solving. Functional programming is a form of declarative programming. In contrast,

    most mainstream languages; including object-oriented programming (OOP) languages such as C#,

    Visual Basic, C++, and Java were designed to primarily support imperative (procedural)

    programming.

    With an imperative approach, a developer writes code that describes in exacting detail the steps that

    the computer must take to accomplish the goal. This is sometimes referred to as algorithmic

    programming. In contrast, a functional approach involves composing the problem as a set of

    functions to be executed. We define carefully the input to each function, and what each function

    returns. The following table describes some of the general differences between these two

    approaches.

    Characteristic Imperative approach Functional approach

    Programmer focus

    How to perform tasks

    (algorithms) and how to

    track changes in state.

    What information is desired and what

    transformations are required.

    State changes Important. Non-existent.

    Order of execution Important. Low importance.

    Primary flow controlLoops, conditionals, and

    function (method) calls.Function calls, including recursion.

    Primary manipulation

    unit

    Instances of structures or

    classes.

    Functions as first-class objects and data

    collections.

  • 8/3/2019 Z-Functional Programming in Haskell

    7/26

    3. FEATURES OF HASKELL

    3.1 PURE

    Haskell is called pure because it does not allow side effects .A side effect is something that affects

    the state of the world. For instance, a function that prints something to the screen is said to be

    side-effecting, as is a function which affects the value of a global variable. Of course, a

    programming language without side effects would be horribly useless; Haskell uses a system of

    monads to isolate all impure computations

    from the rest of the program and perform them in the safe way.

    Purely functional programs operate only on immutable data. This is possible because on each

    modification a new version of a data structure is created and the old one is preserved. Therefore,

    data structures are persistent as it is possible to refer also to old versions of them. If there are no

    more references to the old version the unrefered data can be collected by automatic memory

    management, such as a garbage collector. Often, bigger data structures share their parts between

    versions and do not consume as much memory as all versions separately.

    Pure computations yield the same value each time they are invoked. This property is called

    referential transparency and makes possible to conduct equational reasoning on the code. For

    instance if y = f x and g = h y y then we should be able to replace the definition of g with g = h (f x)

    (f x) and get the same result, only the efficiency might change.

    3.2 STRONGLY TYPED

    Haskell has the following build-in basic data types:

    Bool : False or True

    Char : the set of Unicode characters

    Integer : arbitrary-precision integer numbers

    Int : fixed-precision integer, at least [-229, 229-1]

    http://haskell.org/haskellwiki/Memory_managementhttp://haskell.org/haskellwiki/Memory_managementhttp://haskell.org/haskellwiki/Referential_transparencyhttp://haskell.org/haskellwiki/Memory_managementhttp://haskell.org/haskellwiki/Memory_managementhttp://haskell.org/haskellwiki/Referential_transparency
  • 8/3/2019 Z-Functional Programming in Haskell

    8/26

    Float : real floating-point number, single precision

    Double : double precision

    We can use the following ways to define complex data types out of other data types using data

    constructors :

    Enumeration

    Lists

    Tuples

    Recursion

    List comprehension

    Enumeration is similar to the code types of Pascal,i.e. we define directly all elements of a data type

    by explicitly mentioning them.

    Example: data Weekday = Mo | Tu | We | Th | Fr | Sa | Su

    Mo, Tu, We, Th, Fr, Sa, Su are the data elements of the type Weekday.They are also so-called

    constructors (they can be used to construct the data type).

    Haskell treats lists somewhere between primitive and complex data types, since it already provides

    list constructors and does not require to explicitly define lists If a denotes a data type, then [a]

    denotes lists over this data type. [Integer] denotes list containing integers .[] denotes the empty list .

    The : constructor can also be used to produce lists.

    Tuples are very similar to the record construct in Pascal. Tuples can either use the tuple constructors

    (,,) (with n-1 commas, if we define an n-tuple) or, for parameterized tuple types, we can define

    our own constructors.

    data Date = (Day,Month,Year)

    data CartProduct a = Prod a a

    a is here a type variable indicating the parameter of the parameterized type. Haskell allows a

    programmer to define complex data types using the data statement:

    data Mybool = MyFalse | MyTrue

  • 8/3/2019 Z-Functional Programming in Haskell

    9/26

    3.3 STATICALLY TYPED

    Haskell's static type system defines the formal relationship between types and values .The static

    type system ensures that Haskell programs are type safe; that is, that the programmer has not

    mismatched types in some way. For example, we cannot generally add together two characters, so

    the expression 'a'+'b' is ill-typed. The main advantage of statically typed languages is well-known:

    All type errors are detected at compile-time. Not all errors are caught by the type system; an

    expression such as 1/0 is typable but its evaluation will result in an error at execution time. Still, the

    type system finds many program errors at compile time, aids the user in reasoning about programs,

    and also permits a compiler to generate more efficient code (for example, no run-time type tags or

    tests are required).

    The type system also ensures that user-supplied type signatures are correct. In fact, Haskell's type

    system is powerful enough to allow us to avoid writing any type signatures at all; we say that the

    type system infers the correct types for us. Nevertheless, judicious placement of type signatures is a

    good idea, since type signatures are a very effective form of documentation and help bring

    programming errors to light.

    Haskell automatically infers the most general type. For example, the type of foldr is inferred to be:

    (a->b->b)->b->[a]-> b, which can be read as follows: foldr takes as argument a binary operator,

    whose input values can be of any types a and b and whose

    output value is of type b, and returns as its result a function f which takes a value of type b as input

    and which returns as its result a function f which takes a list of values of type a as input, and

    which returns as its result a value of type b. The inferred type of foldr shows that it can also be used

    to define functions where the input types of its first operator argument are different.

    3.4 FUNCTIONAL

    In a functional language, everything (even a program) is a function. Thus, writing a program is

    actually writing a function. We can write many functions in a single file; that is, we can have many

    programs in a single file. Each function then may use other functions to calculate its result. There

    are many predefined functions available like in other programming languages. These functions are

  • 8/3/2019 Z-Functional Programming in Haskell

    10/26

    included in the Haskell Prelude and in the Haskell Libraries.

    Writing a function consists of two parts. First, we have to define the types for the arguments and the

    result. e.g.:

    doubleIt :: Integer -> Integer

    The name of our new function is doubleIt. The :: separates the name of the function from the type

    definition. The parameter types are separated from each other and from the return type by ->.

    Therefore, the declaration above reads doubleIt is a function with one Integer parameter, returning

    Integer.

    The second part of writing a function is the concrete implementation, e.g.:

    doubleIt x = 2 * x

    The different methods for defining functions are

    Pattern matching

    fac :: Int -> Int

    fac 0 = 1

    fac n = n * fac (n-1)

    Conditional expression

    sign1 :: Int -> String

    sign1 x =

    if x < 0 then "negative"

    else if x > 0 then "positive"

    else "zero"

    http://www.haskell.org/onlinereport/standard-prelude.htmlhttp://www.haskell.org/onlinereport/http://www.haskell.org/onlinereport/standard-prelude.htmlhttp://www.haskell.org/onlinereport/
  • 8/3/2019 Z-Functional Programming in Haskell

    11/26

    Guards

    ab :: Int -> Int

    ab n

    | (n>=0) = n

    | otherwise = (-n)

    Case statement

    cas :: Int -> Int

    cas x =

    case x of0 -> 1

    1 -> 5

    2 -> 2

    "where" clause to hold local definitions

    sumSq :: Int -> Int -> Int

    sumSq x y = sqX + sqY

    where

    sqX = x * x

    sqY = y * y

    3.5 CURRYING

    Currying is the process of transforming a function that takes multiple arguments into a function that

    takes just a single argument and returns another function if any arguments are still needed.

    f :: a -> b -> c

    is the curried form of

    g :: (a, b) -> c

  • 8/3/2019 Z-Functional Programming in Haskell

    12/26

    We can convert these two types in either directions with the Prelude functions curry and uncurry.

    f = curry g

    g = uncurry f

    Both forms are equally expressive. It holds

    f x y = g (x,y) ,

    however the curried form is usually more convenient because it allows partial application.

    add :: Int -> Int -> Int

    add x y = x + y

    addOne = add 1

    In this example, addOne is the result of partially applying add. It is a new function that takes an

    integer, adds 1 to it and returns that as the result. The important property here is that the -> operatoris right associative, and function application is left associative, meaning the type signature of add

    actually looks like this:

    add :: Int -> (Int -> Int)

    This means that add actually takes one argument and returns a function that takes another argument

    and returns an Int. In Haskell, all functions are considered curried: That is, all functions in Haskell

    take just single arguments.

    This is mostly hidden in notation, and so may not be apparent. Let's take the function

    div :: Int -> Int -> Int

    which performs integer division. The expression div 11 2 unsurprisingly evaluates to 5. But there's

    more that's going on than immediately meets the untrained eye. It's a two-part process. First,

    div 11

    is evaluated and returns a function of type

    Int -> Int

    http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curryhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurryhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curryhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurryhttp://haskell.org/haskellwiki/Partial_applicationhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:.http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:divhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:divhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:divhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curryhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurryhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:curryhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:uncurryhttp://haskell.org/haskellwiki/Partial_applicationhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:.http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:divhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:divhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:divhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Int
  • 8/3/2019 Z-Functional Programming in Haskell

    13/26

    Then that resulting function is applied to the value 2, and yields 5. We'll notice that the notation for

    types reflects this: we can read

    Int -> Int -> Int

    incorrectly as "takes two Ints and returns an Int", but what it's really saying is "takes an Int andreturns something of the type Int -> Int" -- that is, it returns a function that takes an Int and returns

    an Int. (One can write the type as Int x Int -> Int if we really mean the former -- but since all

    functions in Haskell are curried, that's not legal Haskell.

    Alternatively, using tuples, we can write (Int, Int) -> Int, but keep in mind that the tuple constructor

    (,) itself can be curried.Much of the time, currying can be ignored. The major advantage of

    considering all functions as curried is theoretical: formal proofs are easier when all functions are

    treated uniformly (one argument in, one result out).

    3.6 LIST COMPREHENSIONS

    List comprehension is a syntactic construct available in some programming languages for creating a

    list based on existing lists. It follows the form of the mathematical set-builder notation (setcomprehension.) as distinct from the use ofmap and filter functions.Consider the following example

    in set builder notation.

    This can be read, "S is the set of all 2*x where x is an item in the set of natural numbers, for which

    x squared is greater than 3."

    In the example:

    x is the variable representing members of an input set.

    The input set is .

    x2 > 3 is a predicate function acting as a filter on members of the input set.

    And is an output function producing members of the new set from members of the

    input set that satisfy the predicate function.

    http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://en.wikipedia.org/wiki/Syntax_of_programming_languageshttp://en.wikipedia.org/wiki/Programming_languagehttp://en.wikipedia.org/wiki/Set-builder_notationhttp://en.wikipedia.org/wiki/Map_(higher-order_function)http://en.wikipedia.org/wiki/Filter_(higher-order_function)http://en.wikipedia.org/wiki/Predicate_(logic)http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Inthttp://en.wikipedia.org/wiki/Syntax_of_programming_languageshttp://en.wikipedia.org/wiki/Programming_languagehttp://en.wikipedia.org/wiki/Set-builder_notationhttp://en.wikipedia.org/wiki/Map_(higher-order_function)http://en.wikipedia.org/wiki/Filter_(higher-order_function)http://en.wikipedia.org/wiki/Predicate_(logic)
  • 8/3/2019 Z-Functional Programming in Haskell

    14/26

    The brackets contain the expression and the vertical bar and comma are separators.

    A list comprehension has the same syntactic components to represent generation of a list in order

    from an input list or iterator:

    A variable representing members of an input list.

    An input list (or iterator).

    An optional predicate expression.

    And an output expression producing members of the output list from members of the input

    iterable that satisfy the predicate.

    Lists are to declarative languages what arrays are to imperative languages. Becuase lists are so

    widely used, a special notation has been introduced in Haskell for constructing lists. This notation is

    called list comprehension (in analogy with set comprehension in set theory). In Haskell's list

    comprehension syntax, this set-builder construct would be written similarly, as:

    s = [ 2*x | x 3 ]

    Here, the list [0..] represents , x^2>3 represents the predicate, and 2*x represents the output

    expression.

    Suppose xs is the list [1,2,3,4,5,6], then the set comprehension

    [ 2*x | x

  • 8/3/2019 Z-Functional Programming in Haskell

    15/26

    3.7 LAZY EVALUATION

    Lazy evaluation (or delayed evaluation) is the technique of delaying a computation until such time

    as the result of the computation is known to be needed.

    The actions of lazy evaluation include: performance increases due to avoiding unnecessary

    calculations, avoiding error conditions in the evaluation of compound expressions, the ability to

    construct infinite data structures, and the ability to define control structures as regular functions

    rather than built-in primitives.

    Languages that use lazy actions can be further subdivided into those that use a call-by-name

    evaluation strategy and those that use call-by-need. Most realistic lazy languages, such as Haskell,

    use call-by-need for performance reasons, but theoretical presentations of lazy evaluation often use

    call-by-name for simplicity.

    The opposite of lazy actions is eager evaluation, also known as strict evaluation. Eager evaluation is

    the evaluation behavior used in most programming languages.

    Haskell evaluates expressions using lazy evaluation:

    1. No expression is evaluated until its value is needed.

    2. No shared expression is evaluated more than once; if the expression is ever evaluated then

    the result is shared between all those places in which it is used.

    Lazy functions are also callednon-strict and evaluate their arguments lazily orby need.

    http://en.wikipedia.org/wiki/Data_structurehttp://en.wikipedia.org/wiki/Control_structurehttp://en.wikipedia.org/wiki/Evaluation_strategyhttp://en.wikipedia.org/wiki/Haskell_(programming_language)http://en.wikipedia.org/wiki/Eager_evaluationhttp://en.wikipedia.org/wiki/Evaluation_strategy#Strict_evaluationhttp://en.wikipedia.org/wiki/Programming_languageshttp://en.wikipedia.org/wiki/Data_structurehttp://en.wikipedia.org/wiki/Control_structurehttp://en.wikipedia.org/wiki/Evaluation_strategyhttp://en.wikipedia.org/wiki/Haskell_(programming_language)http://en.wikipedia.org/wiki/Eager_evaluationhttp://en.wikipedia.org/wiki/Evaluation_strategy#Strict_evaluationhttp://en.wikipedia.org/wiki/Programming_languages
  • 8/3/2019 Z-Functional Programming in Haskell

    16/26

    3.8 RECURSION

    In imperative languages to perform repeated operations we make use of loops.This isn't directlypossible in Haskell, since changing the value of the would not be allowed. However, we can always

    translate a loop into an equivalent recursive form. The idea is to make each loop variable in need of

    updating into a parameter of a recursive function.But recursion is expensive in terms of both time

    and space.

    When a function is called, the computer must "remember" the place it was called from, the return

    address, so that it can return to that location with the result once the call is complete. Typically, this

    information is saved on the stack, a simple list of return locations in order of the times that the call

    locations they describe were reached. Sometimes, the last thing that a function does after

    completing all other operations is to simply call a function, possibly itself, and return its result. But

    in this case, there is no need to remember the place we are calling from instead, we can leave the

    stack alone, and the newly called function will return its result directly to the original caller.

    Converting a call to a branch or jump in such a case is called a tail call optimization. Note that the

    tail call doesn't have to appear lexically after all other statements in the source code; it is only

    important that its result be immediately returned, since the calling function will never get a chance

    to do anything after the call if the optimization is performed.

    Tail recursion (or tail-end recursion) is a special case ofrecursion in which the last operation of

    the function is a recursive call. Such recursions can be easily transformed to iterations.

    Replacing recursion with iteration, manually or automatically, can drastically decrease the amount

    ofstack space used and improve efficiency. This technique is commonly used with functional

    programming languages, where the declarative approach and explicit handling ofstate promote

    the use of recursive functions that would otherwise rapidly fill the call stack.

    http://en.wikipedia.org/wiki/Return_addresshttp://en.wikipedia.org/wiki/Return_addresshttp://en.wikipedia.org/wiki/Recursion_(computer_science)http://en.wikipedia.org/wiki/Iterationhttp://en.wikipedia.org/wiki/Call_stackhttp://en.wikipedia.org/wiki/Functional_programminghttp://en.wikipedia.org/wiki/Functional_programminghttp://en.wikipedia.org/wiki/Declarative_programminghttp://en.wikipedia.org/wiki/State_(computer_science)http://en.wikipedia.org/wiki/Call_stackhttp://en.wikipedia.org/wiki/Return_addresshttp://en.wikipedia.org/wiki/Return_addresshttp://en.wikipedia.org/wiki/Recursion_(computer_science)http://en.wikipedia.org/wiki/Iterationhttp://en.wikipedia.org/wiki/Call_stackhttp://en.wikipedia.org/wiki/Functional_programminghttp://en.wikipedia.org/wiki/Functional_programminghttp://en.wikipedia.org/wiki/Declarative_programminghttp://en.wikipedia.org/wiki/State_(computer_science)http://en.wikipedia.org/wiki/Call_stack
  • 8/3/2019 Z-Functional Programming in Haskell

    17/26

    3.9 HIGHER ORDER FUNCTIONS

    A higher order function is a function that takes other functions as arguments or returns a function as

    result.The three most useful higher order functions aremap,foldandfilter.

    map : It takes in two inputs - a function, and a list. It then applies this function to every element in

    the list.

    map

    ::

    (a

    ->

    b)

    ->

    [a]

    ->

    [b]

    mapfxs =[fx|x map (+1) [1..5]

    [2, 3, 4, 5, 6]

    fold : fold takes in a function and folds it in between the elements of a list.

    fo foldl :: (a -> b -> a) -> a -> [b] -> a

    foldl f z [] = z

    foldl f z (x:xs) = foldl f (f z x) xs

    The command to add the first 5 numbers with fold.

    foldl (+) 0 [1..5]

    Fold take the elements of the list and write them out separately with a space between each.

    1 2 3 4 5

    And now we fold the function into the elements. To do this, we write the function in the empty

    spaces between the elements.

    + 1 + 2 + 3 + 4 + 5

    http://www.cse.unsw.edu.au/~en1000/haskell/hof.html#maphttp://www.cse.unsw.edu.au/~en1000/haskell/hof.html#foldhttp://www.cse.unsw.edu.au/~en1000/haskell/hof.html#filterhttp://www.cse.unsw.edu.au/~en1000/haskell/hof.html#maphttp://www.cse.unsw.edu.au/~en1000/haskell/hof.html#foldhttp://www.cse.unsw.edu.au/~en1000/haskell/hof.html#filter
  • 8/3/2019 Z-Functional Programming in Haskell

    18/26

    Note that there's nothing before the first (+). That's because we can specify a starting point. So that's

    the second input foldl asks for - a starting point. In this case, we said zero, so we'll put it in there.

    0 + 1 + 2 + 3 + 4 + 5

    And all this gives us the final result

    Main> foldl (+) 0 [1..5]

    15

    And if we change the starting point, we get the corresponding answer.

    Main> foldl (+) 1 [1..5]

    16

    Main> foldl (+) 10 [1..5]

    25

    We can also go through the list from right to left, rather than left to right. That's why we use foldl

    and foldr. There are cases where folding from the left gives us different results to folding from the

    right. It all depends on what function we're folding. For example,

    Main> foldr (div) 7 [34,56,12,4,23]

    8

    Main> foldl (div) 7 [34,56,12,4,23]

    0

    filter : It takes in a 'test' and a list, and it chucks out any elements of the list which don't satisfy

    that test.

    filter :: (a -> Bool) -> [a] -> [a]

    filter p xs = [ x | x filter (even) [1..10]

    [2, 4, 6, 8, 10]

    Main> filter (>5) [1..10]

    [6, 7, 8, 9, 10]

    3.10 POLYMORPHISM

    Polymorphism is a programming language feature that allows values of different data types to be

    handled using a uniform interface. The concept of parametric polymorphism applies to both data

    http://en.wikipedia.org/wiki/Programming_languagehttp://en.wikipedia.org/wiki/Data_typehttp://en.wikipedia.org/wiki/Programming_languagehttp://en.wikipedia.org/wiki/Data_type
  • 8/3/2019 Z-Functional Programming in Haskell

    19/26

    types and functions. A function that can evaluate to or be applied to values of different types is

    known as a polymorphic function. A data type that can appear to be of a generalized type (e.g., a list

    with elements of arbitrary type) is designated polymorphic data type like the generalized type from

    which such specializations are made.

    There are two fundamentally different kinds of polymorphism. If the range of actual types that can

    be used is finite and the combinations must be specified individually prior to use, it is called Ad-hoc

    polymorphism. If all code is written without mention of any specific type and thus can be used

    transparently with any number of new types, it is called parametric polymorphism.

    Haskell is a strongly typed language, which means that every expression has a type, and that the

    interpreter can infer the type of an expression from the types of its subexpressions. All the list

    operators, functions and expressions have types.Let's look at the length function. Clearly, length

    returns a number of some kind; in fact, it returns a 32-bit integer, i.e., an Int. And clearly it takes a

    list as argument, but what kind of list? The answer is that it takes any kind of list as argument:

    length :: [a] -> Int

    The type of length's argument is [a], which means a list whose elements are of any type a. This a is

    simply a name standing for any Haskell type; when we evaluate length "word", for example, the a

    stands for (or more precisely, is instantiated to) Char, and when we evaluate length [(1,2)], the a

    stands for (is instantiated to) (Int,Int). This is an example of parametric polymorphism,

    In Haskell, type classes provide a structured way to control ad hoc polymorphism, or

    overloading.Let's start with a simple, but important, example: equality. There are many

    types for which we would like equality defined, but some for which we would not. For example,

    comparing the equality of functions is generally considered computationally intractable, whereas we

    often want to compare two lists for equality. To highlight the issue, consider this definition of the

    function elem which tests for membership in a list:

    x `elem` [] = False

    x `elem` (y:ys) = x==y || (x `elem` ys)

    Intuitively speaking, the type of elem "ought" to be: a->[a]->Bool. But this would imply that == has

    http://en.wikipedia.org/wiki/Function_(programming)http://en.wikipedia.org/wiki/List_(computing)http://en.wikipedia.org/wiki/Ad-hoc_polymorphismhttp://en.wikipedia.org/wiki/Ad-hoc_polymorphismhttp://en.wikipedia.org/wiki/Function_(programming)http://en.wikipedia.org/wiki/List_(computing)http://en.wikipedia.org/wiki/Ad-hoc_polymorphismhttp://en.wikipedia.org/wiki/Ad-hoc_polymorphism
  • 8/3/2019 Z-Functional Programming in Haskell

    20/26

    type a->a->Bool, even though we just said that we don't expect == to be defined for all

    types.Furthermore, even if == were defined on all types, comparing two lists for equality is very

    different from comparing two integers. In this sense, we expect == to be overloaded to carry on

    these various tasks.

    Type classes conveniently solve both of these problems. They allow us to declare which types are

    instances of which class, and to provide definitions of the overloaded operations associated with a

    class.

    Defining classes in Haskell

    class Eq a where

    (==), (/=) ::a->a->Bool

    Creating Instance of Class Eq

    instance Eq Integer where

    x == y = x `integerEq` y

    instance Eq Float where

    x == y=x `floatEq` y

    Class Extension

    classEq a) =>Orda where

    ()::a->a->Bool

    max,min:: a -> a -> a

  • 8/3/2019 Z-Functional Programming in Haskell

    21/26

    Type Classes in Haskell

  • 8/3/2019 Z-Functional Programming in Haskell

    22/26

    4. APPLICATION AREAS

    4.1 NATURAL LANGUAGE INTERFACES

    Parser combinators

    LFP has been used in a conventional way to implement a range of parsers that have already been

    implemented in other programming languages. parser combinators is an approach to parser

    construction which is unique to functional programming. The use of parser combinators was first

    proposed by Burge in 1975, The idea is to construct more complex language processors from

    simpler processors by combining them using higher-order functions (the parser combinators). This

    approach was developed further by Wadler [1985] who suggested that recognizers and parsers

    should return a list of results. Multiple entries in the list are returned for ambiguous input, and an

    empty list of successes denotes failure to recognize the input. Fairburn promoted combinator

    parsing by using it as an example of a programming style in which form follows function: a

    language processor that is constructed using parser combinators has a structure which is very similar

    to the grammar defining the language to be processed.

    Construction of Morphologies

    A morphology is a system which explains the internal structure of words. Regular nouns have

    relatively simple morphological structure. For example, cat, cat++s, and cat++++s,

    whereas irregular nouns and verbs have more complex morphology. The morphology of a particular

    language can be defined using a set of inflection tables. The conventional approach to

    morphological recognition is to compile the tables into finite state automata, and then to parse

    words as regular expressions.As an alternative, Pembeci [1995] has built a morphological analyzer

    for Turkish using parser combinators

    implemented in Miranda and claims that the analyzer can parse approximately 99% of all word

    forms in Turkish. Pembeci also claims that all morphological processes have been

  • 8/3/2019 Z-Functional Programming in Haskell

    23/26

    implemented, and that a number of advantages result from use of parser combinators, including

    clarity and modifiability of the code. Forsberg [2004], and Forsberg and Ranta [2004] have

    developed an alternative approach, called Functional Morphology which is implemented in Haskell.

    It is based on Huets toolkit, Zen, [Huet 2003, 2004] which Huet used to build a morphology for

    Sanskrit. In this approach, inflection parameters are defined using algebraic data types,and

    paradigm tables are implemented as finite functions defined over these types.

    Semantic analysis

    Computationally-tractable versions of Montague-like semantic theories can be implemented in LFP

    by the direct encoding of the higher-order functional semantics.

    4.2 PARALLEL PROGRAMMING

    Nested Data Parallelism

    Nested DP is great for programmers due to its modularity. It opens up a much wider range of

    applications:

    Sparse arrays, variable grid adaptive methods (e.g. Barnes-Hut)

    Divide and conquer algorithms (e.g. sort)

    Graph algorithms (e.g. shortest path, spanning trees)

    Physics engines for games, computational graphics (e.g. Delauny triangulation)

    Machine learning, optimisation, constraint solving.

  • 8/3/2019 Z-Functional Programming in Haskell

    24/26

    5. HASKELL IN PRACTICE

    LOLITA : LOLITA is a natural language processing (NLP) system providing both core NLP

    capabilities and a number of prototype applications. The core of the system is based on three main

    capabilities:

    1. conversion of English language text to an internal (semantic network based)

    representation of the text's meaning

    2. inferences in the semantic network

    3. conversion of portions of the semantic network to English

    Linkchk : Linkchk is a network interface link ping monitor. It supports both IPv4 and IPv6. It

    works by monitoring the routing table and pinging the gateway (next hop) of a network interface.

    When the link is up and functioning the ping time is displayed in a small gtk window, otherwise the

    link status is displayed. linkchk can also run in a tty.

    HWS-WP : The Haskell Web-Server With Plugins (HWS-WP) is a. simple HTTP server written

    in Haskell, originally implemented by Simon Marlow and updated by Martin Sjogren.

    Hoogle : Hoogle is a Haskell API search engine. It allows us to search by either name, or by

    approximate type signature. The standard web interface to Hoogle is available at

    http://www.haskell.org/hoogle/.

    House : Haskell User's Operating System and Environment.House is a demo of software written

    in Haskell, running in a standalone environment. It is a system than can serve as a platform for

    exploring various ideas relating to low-level and system-level programming in a high-level

    functional language.

    http://www.haskell.org/hoogle/http://www.haskell.org/http://www.haskell.org/hoogle/http://www.haskell.org/
  • 8/3/2019 Z-Functional Programming in Haskell

    25/26

    6. CONCLUSION

    Haskell 98 is complete and is the current official definition of Haskell. We expect that this

    language will be supported in the long term even as new extensions are added to Haskell; compilers

    will continue to support Haskell 98 (via a special flag).

    The language evolves and numerous extensions have been proposed and many of them have been

    implemented in some Haskell systems; for example pattern guards, scoped type variables, multi-

    parameter type classes, local universal and existential quantification. The Haskell mailing lists are a

    forum for discussing new language features. Haskell' is the next official version.

    http://www.haskell.org/haskellwiki/?title=Haskell_mailing_lists&action=edithttp://www.haskell.org/haskellwiki/?title=Haskell_mailing_lists&action=edit
  • 8/3/2019 Z-Functional Programming in Haskell

    26/26

    http://www.haskell.org/http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html