...
 
Commits (2)
......@@ -23,7 +23,7 @@ There is no formal textbook, but we recommend the Haskell wikibook as a primary
## Assignments
- [Assignment 1](/assignments/assign1.html) (out: 1/14, due: 1/21). Solutions [here](/solutions/assign1.html).
- [Assignment 2](/assignments/assign2.html) (out: 1/21, due: 1/28).
- [Assignment 2](/assignments/assign2.html) (out: 1/21, due: 1/28). Solutions [here](/solutions/assign2.html).
- [Assignment 3](/assignments/assign3.html) (out: 1/29, due: 2/6).
## Prerequisites
......
......@@ -4,45 +4,51 @@ title: Assignment 2
## Problems
1. Integers, like booleans, do not have a natural associative operation.
However, both addition and multiplication are associative operations on
integers. Write `Semigroup` instances for the `Sum` and `Product` types
wrapping `Int` in the starter code, mirroring the implementations of `Any`
and `All`.
See code below.
2. The default given above has $O(n)$ performance, which is less efficient than
the best general implementation. Using the associative property of `<>`,
provide a more efficient implementation, `stimes'`, with time
complexity $O(\log n)$.
```haskell
stimes' :: (Semigroup a, Integral b) => b -> a -> a
stimes' n x
## Problem 1
Integers, like booleans, do not have a natural associative operation.
However, both addition and multiplication are associative operations on
integers. Write `Semigroup` instances for the `Sum` and `Product` types
wrapping `Int` in the starter code, mirroring the implementations of `Any`
and `All`.
_See solution to Problem 3._
## Problem 2
The default given above has $O(n)$ performance, which is less efficient than
the best general implementation. Using the associative property of `<>`,
provide a more efficient implementation, `stimes'`, with time
complexity $O(\log n)$.
```haskell
stimes' :: (Semigroup a, Integral b) => b -> a -> a
stimes' n x
| n <= 0 = error "positive multiplier expected"
| n == 1 = x
| even n = stimes' m x <> stimes' m x
| otherwise = stimes' (m + 1) x <> stimes' m x
where m = n `div` 2
```
## Problem 3
While $O(\log n)$ is the best possible performance in general, specific
instances can perform even better. Extend your instances for `Sum` and `Product`
with $O(1)$ implementations of `stimes`.
```haskell
instance Semigroup Sum where
(Sum a) <> (Sum b) = Sum $ a + b
stimes n (Sum x)
| n <= 0 = error "positive multiplier expected"
| otherwise = Sum $ x * (fromIntegral n)
instance Semigroup Product where
(Product a) <> (Product b) = Product $ a * b
stimes n (Product x)
| n <= 0 = error "positive multiplier expected"
| n == 1 = x
| even n = stimes' m x <> stimes' m x
| otherwise = stimes' (m + 1) x <> stimes' m x
where m = n `div` 2
```
3. While $O(\log n)$ is the best possible performance in general, specific
instances can perform even better. Extend your instances for `Sum` and `Product`
with $O(1)$ implementations of `stimes`.
```haskell
instance Semigroup Sum where
(Sum a) <> (Sum b) = Sum $ a + b
stimes n (Sum x)
| n <= 0 = error "positive multiplier expected"
| otherwise = Sum $ x * (fromIntegral n)
instance Semigroup Product where
(Product a) <> (Product b) = Product $ a * b
stimes n (Product x)
| n <= 0 = error "positive multiplier expected"
| otherwise = Product $ x ^ (fromIntegral n)
```
\ No newline at end of file
| otherwise = Product $ x ^ (fromIntegral n)
```
\ No newline at end of file