Lecture Notes on Algebraic Data Types and Parametric Types in Haskell, Study notes of Programming Languages

A set of lecture notes from a computer science course (cpsc 326) held in spring 2013. The notes cover the topics of algebraic data types and user-defined parametric types in haskell. Comparisons between haskell and c/c++, pattern matching with algebraic data types, and the use of maybe type instead of error handling.

Typology: Study notes

2012/2013

Uploaded on 09/28/2013

noob
noob 🇮🇳

4.4

(25)

105 documents

1 / 12

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Lecture Notes CPSC 326 (Spring 2013)
Today ...
Algebraic data types (cont.)
User defined parametric types
S. Bowers 1 of 12
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download Lecture Notes on Algebraic Data Types and Parametric Types in Haskell and more Study notes Programming Languages in PDF only on Docsity!

Today ...

  • Algebraic data types (cont.)
  • User defined parametric types

Comparison to other languages

-- Haskell // C/C++ data Book = Book struct Book { Integer int id; String char* name; [String] char** authors; };

Q: What are the differences?

  • fields in data types are positional and anonymous (unnamed)
  • e.g., Book b1; b1.name = "Neuromance";
  • we are accessing the 2nd field by “name”

-- Haskell // C/C++ data Book = Red enum Color { | Blue RED, | Green BLUE, deriving (Show, Eq) GREEN };

  • Deriving Eq allows comparisons, e.g., Red == Green

Q: What are the differences?

  • in C/C++ enum values are integers
  • value constructors are not integers in Haskell

Pattern matching with algebraic data types

Can use data constructors and fields with pattern matching

  • Simple example bookID (Book id title authors) = id bookTitle (Book id title authors) = title bookAuthros (Book id title authors) = authors
  • Can simplify with wildcards

bookID (Book id _ _) = id bookTitle (Book _ title _) = title bookAuthros (Book _ title _) = authors

We can get rid of the “boilerplate”

  • Add accessors to the data type data Book = Book bookID :: ID, bookTitle :: Title, bookAuthors :: Authors deriving (Show)
  • And then use the functions *Main> let b1 = Book 035 "Neuromancer" ["Gibson"]

*Main> bookTitle b "Neuromancer"

*Main> :type bookTitle bookTitle :: Book -> Title

  • Can also use “record syntax”

*Main> let b2 = Book { bookTitle = "The Stranger", bookID = 45, bookAuthors = ["Camus"] }

*Main> bookTitle b "Neuromancer"

  • In record syntax
    • Fields are named (via accessors)
    • Fields can be given in any order (not just by position)

Prelude> m Just "something"

Prelude> :type m m2 :: Maybe [Char]

  • A simple (unrealistic) use of the Maybe type

myDiv x y | y == 0 = Nothing | otherwise = Just (x / y)

*Main> :type myDiv (Fractional a) => a -> a -> Maybe a

*Main> myDiv 1 0 Nothing

*Main> myDiv 1 1 Just 1.

Maybe versus Error

The standard “error” function

error :: String -> a

  • Given a string produces a value of any type a

Why does error return any type?

  • Always returns a value of the “correct” type
  • So can be called from anywhere, without causing a type conflict
  • error never returns though ...
    • aborts execution (exception) without returning an actual value

Using error to return the second element of a list

sndL :: [a] -> a sndL (:x:) = x sndL _ = error "List too short!"

*Main> sndL [] *** Exception: List too short!

*Main> sndL [1] *** Exception: List too short!

*Main> sndL [1,2] 2

A more involved parametric type example

Representing a binary search tree (BST)

data Tree a = Node a (Tree a) (Tree a) | Nil deriving (Show, Eq)

Q: Create the following trees ...

  1. ("a")
  2. ("b") / ("a")
  3. ("d") /
    ("b") ("e") /
    ("a") ("c")
  4. Node "a" Nil Nil
  5. Node "b" (Node "a" Nil Nil) Nil
  6. Node "d" (Node "b" (Node "a" Nil Nil) (Node "c" Nil Nil)) (Node "e" Nil Nil)

Implementing a BST

isEmpty :: Tree a -> Bool isEmpty Nil = True isEmpty _ = False

size :: (Num b) => Tree a -> b size Nil = 0 size (Node _ l r) = 1 + (size l) + (size r)

height :: (Num b) => Tree a -> b height Nil = 0 height (Node _ l r) = 1 + max (height 1) (height r)

insert :: (Ord a) => a -> Tree a -> Tree a insert x Nil = Node x Nil Nil insert x (Node y l r ) | x < y = Node y (insert x l) r | otherwise = Node y l (insert x r)

find :: (Ord a) => a -> Tree a -> Bool find x Nil = False find x (Node y l r) | x == y = True | x < y = find x l | otherwise = find x r