- Home
- Documents
*Structural polymorphism in Generic Haskell Haskell I Haskell is a statically typed, pure functional*

If you can't read please download the document

View

1Download

0

Embed Size (px)

Structural polymorphism in Generic Haskell

Andres Löh

andres@cs.uu.nl

5 February 2005

Overview

About Haskell

Genericity and other types of polymorphism

Examples of generic functions

Generic Haskell

Overview

About Haskell

Genericity and other types of polymorphism

Examples of generic functions

Generic Haskell

Haskell I Haskell is a statically typed, pure functional language with

lazy evaluation. I Functions are defined by pattern matching.

factorial 0 = 1 factorial n = n · factorial (n− 1)

I Every function has a type that usually can be inferred by the compiler.

factorial :: Int → Int

I Functions with multiple arguments are written in curried style.

and :: Bool → Bool → Bool and True True = True and = False

Haskell I Haskell is a statically typed language. I Functions are defined by pattern matching.

factorial 0 = 1 factorial n = n · factorial (n− 1)

I Every function has a type that usually can be inferred by the compiler.

factorial :: Int → Int

I Functions with multiple arguments are written in curried style.

and :: Bool → Bool → Bool and True True = True and = False

Haskell I Haskell is a statically typed language. I Functions are defined by pattern matching.

factorial 0 = 1 factorial n = n · factorial (n− 1)

I Every function has a type that usually can be inferred by the compiler.

factorial :: Int → Int

I Functions with multiple arguments are written in curried style.

and :: Bool → Bool → Bool and True True = True and = False

Haskell I Haskell is a statically typed language. I Functions are defined by pattern matching.

factorial 0 = 1 factorial n = n · factorial (n− 1)

I Every function has a type that usually can be inferred by the compiler.

factorial :: Int → Int

I Functions with multiple arguments are written in curried style.

and :: Bool → Bool → Bool and True True = True and = False

Haskell I Haskell is a statically typed language. I Functions are defined by pattern matching.

factorial 0 = 1 factorial n = n · factorial (n− 1)

I Every function has a type that usually can be inferred by the compiler.

factorial :: Int → Int

I Functions with multiple arguments are written in curried style.

and :: Bool → Bool → Bool and True True = True and = False

User-defined datatypes

I New datatypes can be defined in Haskell using the data construct:

data Nat = Zero | Succ Nat

The expression Succ (Succ (Succ Zero)) represents the number 3.

I Functions are often defined recursively, by induction on the structure of a datatype:

plus :: Nat → Nat → Nat plus m Zero = m plus m (Succ n) = Succ (plus m n)

User-defined datatypes

I New datatypes can be defined in Haskell using the data construct:

data Nat = Zero | Succ Nat

The expression Succ (Succ (Succ Zero)) represents the number 3.

I Functions are often defined recursively, by induction on the structure of a datatype:

plus :: Nat → Nat → Nat plus m Zero = m plus m (Succ n) = Succ (plus m n)

Haskell datatypes

Haskell’s data construct is extremely flexible.

data TimeInfo = AM | PM | H24 data Package = P String Author Version Date data Maybe α = Nothing | Just α data [α ] = [ ] | α : [α ] data Tree α = Leaf α | Node (Tree α) (Tree α)

Common structure: I parametrized over a number of arguments I several constructors / alternatives I multiple fields per constructor I possibly recursion

Haskell datatypes

Haskell’s data construct is extremely flexible.

data TimeInfo = AM | PM | H24 data Package = P String Author Version Date data Maybe α = Nothing | Just α data [α ] = [ ] | α : [α ] data Tree α = Leaf α | Node (Tree α) (Tree α)

Common structure: I parametrized over a number of arguments I several constructors / alternatives I multiple fields per constructor I possibly recursion

Haskell datatypes

Haskell’s data construct is extremely flexible.

data TimeInfo = AM | PM | H24 data Package = P String Author Version Date data Maybe α = Nothing | Just α data [α ] = [ ] | α : [α ] data Tree α = Leaf α | Node (Tree α) (Tree α)

Common structure: I parametrized over a number of arguments I several constructors / alternatives I multiple fields per constructor I possibly recursion

Haskell datatypes

Haskell’s data construct is extremely flexible.

Haskell datatypes

Haskell’s data construct is extremely flexible.

Haskell datatypes

Haskell’s data construct is extremely flexible.

Overview

About Haskell

Genericity and other types of polymorphism

Examples of generic functions

Generic Haskell

Parametric polymorphism

Haskell allows to express functions that work on all datatypes in a uniform way.

id :: ∀α.α → α id x = x

swap :: ∀α β.(α, β) → (β, α) swap (x, y) = (y, x)

head :: ∀α.[α ] → α head (x : xs) = x

We can take the head of a list of Packages, or swap a tuple of two Trees.

When are two values equal?

It is easy to define an equality function for a specific datatype.

I Both values must belong to the same alternative. I The corresponding fields must be equal.

When are two values equal?

It is easy to define an equality function for a specific datatype.

I Both values must belong to the same alternative. I The corresponding fields must be equal.

They must belong to the same alternative

data TimeInfo = AM | PM | H24 (= =)TimeInfo :: TimeInfo → TimeInfo → Bool AM = =TimeInfo AM = True PM = =TimeInfo PM = True H24 = =TimeInfo H24 = True

= =TimeInfo = False

The corresponding fields must be equal

data Package = PD String Author Version Date (= =)Package :: Package → Package → Bool (PD n c v d) = =Package (PD n′ c′ v′ d′) = n = =String n′

∧ c = =Author c′ ∧ v = =Version v′ ∧ d = =Date d′

Equality for parametrized datatypes

data Maybe α = Nothing | Just α (= =)Maybe :: ∀α.(α → α → Bool) → (Maybe α → Maybe α → Bool) (= =)Maybe (= =)α Nothing Nothing = True (= =)Maybe (= =)α (Just x) (Just x

′) = x = =??? x′

(= =)Maybe (= =)α = False

I We can define the equality for parametrized datatypes, but for that, we must know the equality function(s) for the argument(s).

I The equality function depends on itself.

Equality for parametrized datatypes

data Maybe α = Nothing | Just α (= =)Maybe :: ∀α.(α → α → Bool) → (Maybe α → Maybe α → Bool) (= =)Maybe (= =)α Nothing Nothing = True (= =)Maybe (= =)α (Just x) (Just x

′) = x = =α x′

(= =)Maybe (= =)α = False

I We can define the equality for parametrized datatypes, but for that, we must know the equality function(s) for the argument(s).

I The equality function depends on itself.

Equality for parametrized datatypes

data Maybe α = Nothing | Just α (= =)Maybe :: ∀α.(α → α → Bool) → (Maybe α → Maybe α → Bool) (= =)Maybe (= =)α Nothing Nothing = True (= =)Maybe (= =)α (Just x) (Just x

′) = x = =α x′

(= =)Maybe (= =)α = False

I We can define the equality for parametrized datatypes, but for that, we must know the equality function(s) for the argument(s).

I The equality function depends on itself.

Equality for parametrized datatypes

′) = x = =α x′

(= =)Maybe (= =)α = False

I The equality function depends on itself.

Equality isn’t parametrically polymorphic