### Statistics

### Views

- Total Views
- 2,407
- Views on SlideShare
- 2,398
- Embed Views

### Actions

- Likes
- 0
- Downloads
- 59
- Comments
- 0

### Accessibility

### Categories

### Upload Details

Uploaded via SlideShare as Adobe PDF

### Usage Rights

© All Rights Reserved

Like this presentation? Why not share!

- Real World Haskell: Lecture 4 by Bryan O'Sullivan 2405 views
- Real-world-haskell by eusys 3585 views
- Programming haskell chapter10 by Ruicc Rail 5475 views
- An Introduction to Functional Progr... by Michel Rijnders 4438 views
- Quaternion arithmetic - by Elmer 3267 views
- Cibelle celestino silva and roberto... by ZeroField Energy 729 views
- DEFUN 2008 - Real World Haskell by Bryan O'Sullivan 6265 views
- Quaternion to axis by Arric Tan 7 views
- Deriving Scalaz by nkpart 6337 views
- 02. haskell motivation by Sebastian Rettig 480 views
- Haskell Introduction by albertlee 2264 views
- Eugene salamin application of qua... by ZeroField Energy 709 views

**2,407**views

- Total Views
- 2,407
- Views on SlideShare
- 2,398
- Embed Views
- 9

- Likes
- 0
- Downloads
- 59
- Comments
- 0

http://www.slideshare.net | 5 |

http://www.slideee.com | 2 |

https://www.linkedin.com | 2 |

Uploaded via SlideShare as Adobe PDF

© All Rights Reserved

- Real World Haskell: Lecture 5 Bryan O’Sullivan 2009-11-04
- Adding quaternions We add two quaternions by adding their coeﬃcients. a+ bi + cj + dk + w+ xi + yj + zk = (a + w ) + (b + x)i + (c + y )j + (d + z)k Or, in Haskell: addQ (Q a b c d ) (Q w x y z ) = Q ( a+w) ( b+x ) ( c+y ) ( d+z )
- Subtracting quaternions Subtraction is deﬁned similarly. subQ (Q a b c d ) (Q w x y z ) = Q ( a−w) ( b−x ) ( c−y ) ( d−z )
- Typeclass inheritance The Eq typeclass that we met last week lets us compare values for equality. For many values, we want to be able to compare them for (total) ordering, for which we use the Ord typeclass. c l a s s ( Eq a ) = Ord a where > compare : : a −> a −> Ordering Notice the constraint on the Ord class: this states that in order for a type to be an instance of Ord, it must already be an instance of Eq.
- The Num typeclass Haskell deﬁnes a typeclass named Num that lets us express common arithmetic operations: c l a s s ( Eq a , Show a ) = Num a where > (+) : : a −> a −> a (∗) : : a −> a −> a (−) : : a −> a −> a negate : : a −> a abs : : a −> a {− e t c . −}
- Num and quaternions On ﬁrst glance, we can easily ﬁt our Quaternion type into the Num class. i n s t a n c e Num Q u a t e r n i o n where (+) = addQ (−) = subQ {− ??? −} We quickly run into problems: it’s not obvious what negate or abs should do. Maybe we can do something with multiplication, though?
- Multiplying quaternions If we can remember the identities i2 = j2 = k2 = ijk = −1 Then multiplication of quaternions falls out from the usual laws of arithmetic, but takes a complicated form: a + bi + cj + dk ∗ w + xi + y j + zk = aw − bx − cy − dz + (ax + bw + cz − dy )i + (ay − bz + cw + dx)j + (az + by − cx + dw )k
- Multiplying quaternions in Haskell It’s easy to convert our equation into executable form: mulQ (Q a b c d ) (Q w x y z ) = Q ( a ∗w − b∗ x − c ∗ y − d∗ z ) ( a ∗ x + b∗w + c ∗ z − d∗ y ) ( a ∗ y − b∗ z + c ∗w + d∗ x ) ( a ∗ z + b∗ y − c ∗ x + d∗w)
- Multiplying quaternions in Haskell It’s easy to convert our equation into executable form: mulQ (Q a b c d ) (Q w x y z ) = Q ( a ∗w − b∗ x − c ∗ y − d∗ z ) ( a ∗ x + b∗w + c ∗ z − d∗ y ) ( a ∗ y − b∗ z + c ∗w + d∗ x ) ( a ∗ z + b∗ y − c ∗ x + d∗w) Does this mean that we should augment our deﬁnition of Num as follows? i n s t a n c e Num Q u a t e r n i o n where ( ∗ ) = mulQ {− e t c . −}
- Arithmetic laws There are some laws that are so ingrained into our minds that we never think about them: m+n =n+m (commutative law of addition) (m + n) + k = m + (n + k) (associative law of addition) mn = nm (commutative law of multiplication) (mn)k = m(nk) (associative law of multiplication)
- Laws for quaternions We can see by simple inspection that addition over quaternions must satisfy the commutative and associative laws of normal arithmetic. We used those familiar arithmetic laws to derive the formula for quaternion multiplication, but do quaternions satisfy the commutative law of multiplication? Prelude> let a = Q 2 0 9 0 Prelude> let b = Q 0 9 0 2 Prelude> a ‘mulQ‘ b Q 0.0 36.0 0.0 (-77.0) Prelude> b ‘mulQ‘ a Q 0.0 0.0 0.0 85.0
- Laws: made to be broken? When you write or use a typeclass, there’s an implied understanding that you’ll obey its laws1 . Code that uses Eq relies on the fact that if a == b is True, then b == a will be True too, and a /= b will be False. Similarly, code that uses Num implicitly relies on the commutativity and associativity of addition and multiplication. 1 Unfortunately, these laws are often undocumented.
- Laws: made to be broken? When you write or use a typeclass, there’s an implied understanding that you’ll obey its laws1 . Code that uses Eq relies on the fact that if a == b is True, then b == a will be True too, and a /= b will be False. Similarly, code that uses Num implicitly relies on the commutativity and associativity of addition and multiplication. Neither the type system nor any other aspect of Haskell will help you to do the heavy lifting here: The burden is on you, the creator of a type, to ensure that if you make it an instance of a typeclass, that it follows the laws. 1 Unfortunately, these laws are often undocumented.
- A sketchy approach Since quaternion multiplication is not commutative, we should not implement (∗). But what more should we do? For instance, we could partially implement Num: i n s t a n c e Num Q u a t e r n i o n where (+) = addQ ( ∗ ) = undefined What eﬀect does this have on code that tries to use multiplication? Prelude> scalar 2 * scalar 3 *** Exception: Prelude.undefined This is not very satisfactory behaviour.
- Playing fast and loose Of course, Haskell itself doesn’t escape the sin bin. What happens to those fancy laws in the presence of inexact arithmetic? Prelude> let a = 1e20 :: Double Prelude> (a + (-a)) + 1 1.0 Prelude> a + ((-a) + 1) 0.0 (This is the same behaviour as every other language that implements ﬂoating point, by the way.) A conclusion? You can violate the rules, but the compiler can’t remind you that you’re cheating.
- Code that might fail You’ve probably seen this behaviour by now: Prelude> 1 ‘div‘ 0 *** Exception: divide by zero These exceptions are often annoying, because we can’t easily catch and handle them. There exists a predeﬁned type we can use to deal with these cases: data Maybe a = Nothing | Just a Notice that this type is parameterized, so we can have types such as Maybe Int, or Maybe (String, Bool), or so on.
- Safer functions via Maybe Safer integer division: a ‘ s a f e D i v ‘ 0 = Nothing a ‘ s a f e D i v ‘ b = Just ( a ‘ div ‘ b ) A safer version of head: safeHead [ ] = Nothing s a f e H e a d ( x : ) = Just x
- Exercise time! You should be familiar with the map function by now: map : : ( a −> b ) −> [ a ] −> [ b ] Write the equivalent function for the Maybe type: mapMaybe : : ( a −> b ) −> Maybe a −> Maybe b
- Binary trees data Tree a = Empty | Node a ( Tree a ) ( Tree a ) d e r i v i n g ( Eq , Ord , Show) l e a f v = Node v Empty Empty someOldTree = Node ( l e a f ” f o o ” ) ( Node ( l e a f ” b a r ” ) ( Node ( l e a f ” baz ” ) Empty ) )
- Sizing a tree s i z e Empty = 0 s i z e Node a b = 1 + s i z e a + s i z e b
- Mapping again What should this function look like? mapTree : : ( a −> b ) −> Tree a −> Tree b
- Generalising mapping So far, we’ve seen three diﬀerent container types, with three diﬀerent map-like functions: map : : ( a −> b ) −> [ a ] −> [ b ] mapMaybe : : ( a −> b ) −> Maybe a −> Maybe b mapTree : : ( a −> b ) −> Tree a −> Tree b It turns out we can write a typeclass to generalise this idea: c l a s s Functor f where fmap : : ( a −> b ) −> f a −> f b i n s t a n c e Functor Maybe where fmap = mapMaybe
- Homework—binary search trees Turn the Tree type into a binary search tree by deﬁning the following functions: i n s e r t : : ( Ord a ) = a −> Tree a −> Tree a > c o n t a i n s : : ( Ord a ) = a −> Tree a −> Bool >
- Homework—key/value containers Adapt your binary search tree code for use to create a simple key/value container: type Map a b = Tree ( a , b ) insertItem : : ( Ord a ) = a −> b −> Map a b −> Map a b > lookupByKey : : ( Ord a ) = a −> Map a b −> Maybe b > listToMap : : ( Ord a ) = [ ( a , b ) ] −> Map a b > mapToList : : Map a b −> [ ( a , b ) ] minItem : : ( Ord a ) = Map a b −> Maybe ( a , b ) >

Full NameComment goes here.