-
Notifications
You must be signed in to change notification settings - Fork 299
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add exercises! * Update contents.xcplayground
- Loading branch information
1 parent
1998e89
commit 5c16053
Showing
15 changed files
with
204 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
...-types/Algebraic Data Types.playground/Pages/02-Exercises.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/*: | ||
# Algebraic Data Types Exercises | ||
|
||
1. What algebraic operation does the function type `(A) -> B` correspond to? Try explicitly enumerating all the values of some small cases like `(Bool) -> Bool`, `(Unit) -> Bool`, `(Bool) -> Three` and `(Three) -> Bool` to get some intuition. | ||
*/ | ||
// TODO | ||
/*: | ||
2. Consider the following recursively defined data structure. Translate this type into an algebraic equation relating `List<A>` to `A`. | ||
*/ | ||
indirect enum List<A> { | ||
case empty | ||
case cons(A, List<A>) | ||
} | ||
// TODO | ||
/*: | ||
3. Is `Optional<Either<A, B>>` equivalent to `Either<Optional<A>, Optional<B>>`? If not, what additional values does one type have that the other doesn’t? | ||
*/ | ||
// TODO | ||
/*: | ||
4. Is `Either<Optional<A>, B>` equivalent to `Optional<Either<A, B>>`? | ||
*/ | ||
// TODO | ||
/*: | ||
5. Can you overload the `*` and `+` infix operators with functions that take any type and build up an algebraic representation using `Pair` and `Either`? | ||
*/ | ||
// TODO |
7 changes: 5 additions & 2 deletions
7
0004-algebraic-data-types/Algebraic Data Types.playground/contents.xcplayground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<playground version='5.0' target-platform='macos'> | ||
<timeline fileName='timeline.xctimeline'/> | ||
<playground version='6.0' target-platform='macos'> | ||
<pages> | ||
<page name='01-Episode'/> | ||
<page name='02-Exercises'/> | ||
</pages> | ||
</playground> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
...ions/Higher-Order Functions.playground/Pages/02-Exercises.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/*: | ||
# Higher-Order Functions Exercises | ||
|
||
1. Write `curry` for functions that take 3 arguments. | ||
*/ | ||
// TODO | ||
/*: | ||
2. Explore functions and methods in the Swift standard library, Foundation, and other third party code, and convert them to free functions that compose using `curry`, `zurry`, `flip`, or by hand. | ||
*/ | ||
// TODO | ||
/*: | ||
3. Explore the associativity of function arrow `->`. Is it fully associative, _i.e._ is `((A) -> B) -> C` equivalent to `(A) -> ((B) -> C)`, or does it associate to only one side? Where does it parenthesize as you build deeper, curried functions? | ||
*/ | ||
// TODO | ||
/*: | ||
4. Write a function, `uncurry`, that takes a curried function and returns a function that takes two arguments. When might it be useful to un-curry a function? | ||
*/ | ||
// TODO | ||
/*: | ||
5. Write `reduce` as a curried, free function. What is the configuration _vs._ the data? | ||
*/ | ||
// TODO | ||
/*: | ||
6. In programming languages that lack sum/enum types one is tempted to approximate them with pairs of optionals. Do this by defining a type `struct PseudoEither<A, B>` of a pair of optionals, and prevent the creation of invalid values by providing initializers. | ||
|
||
This is “type safe” in the sense that you are not allowed to construct invalid values, but not “type safe” in the sense that the compiler is proving it to you. You must prove it to yourself. | ||
*/ | ||
// TODO | ||
/*: | ||
7. Explore how the free `map` function composes with itself in order to transform a nested array. More specifically, if you have a doubly nested array `[[A]]`, then `map` could mean either the transformation on the inner array or the outer array. Can you make sense of doing `map >>> map`? | ||
*/ | ||
// TODO |
7 changes: 5 additions & 2 deletions
7
0005-higher-order-functions/Higher-Order Functions.playground/contents.xcplayground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<playground version='5.0' target-platform='macos'> | ||
<timeline fileName='timeline.xctimeline'/> | ||
<playground version='6.0' target-platform='macos' display-mode='rendered'> | ||
<pages> | ||
<page name='01-Episode'/> | ||
<page name='02-Exercises'/> | ||
</pages> | ||
</playground> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
...-setters/Functional Setters.playground/Pages/02-Exercises.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/*: | ||
# Functional Setters Exercises | ||
|
||
1. As we saw with free `map` on `Array`, define free `map` on `Optional` and use it to compose setters that traverse into an optional field. | ||
*/ | ||
// TODO | ||
/*: | ||
2. Take the following `User` struct and write a setter for its `name` property. Add another property, and add a setter for it. What are some potential issues with building these setters? | ||
*/ | ||
struct User { | ||
let name: String | ||
} | ||
// TODO | ||
/*: | ||
3. Add a `location` property to `User`, which holds a `Location`, defined below. Write a setter for `userLocationName`. Now write setters for `userLocation` and `locationName`. How do these setters compose? | ||
*/ | ||
struct Location { | ||
let name: String | ||
} | ||
// TODO | ||
/*: | ||
4. Do `first` and `second` work with tuples of three or more values? Can we write `first`, `second`, `third`, and `nth` for tuples of _n_ values? | ||
*/ | ||
// TODO | ||
/*: | ||
5. Write a setter for a dictionary that traverses into a key to set a value. | ||
*/ | ||
// TODO | ||
/*: | ||
6. What is the difference between a function of the form `((A) -> B) -> (C) -> (D)` and one of the form `(A) -> (B) -> (C) -> D`? | ||
*/ | ||
// TODO |
7 changes: 5 additions & 2 deletions
7
0006-functional-setters/Functional Setters.playground/contents.xcplayground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<playground version='5.0' target-platform='macos'> | ||
<timeline fileName='timeline.xctimeline'/> | ||
<playground version='6.0' target-platform='macos' display-mode='rendered'> | ||
<pages> | ||
<page name='01-Episode'/> | ||
<page name='02-Exercises'/> | ||
</pages> | ||
</playground> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
...paths/Setters and Key Paths.playground/Pages/02-Exercises.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/*: | ||
# Setters and Key Paths Exercises | ||
|
||
1. In this episode we used `Dictionary`’s subscript key path without explaining it much. For a `key: Key`, one can construct a key path `\.[key]` for setting a value associated with `key`. What is the signature of the setter `prop(\.[key])`? Explain the difference between this setter and the setter `prop(\.[key]) <<< map`, where `map` is the optional map. | ||
*/ | ||
// TODO | ||
/*: | ||
2. The `Set<A>` type in Swift does not have any key paths that we can use for adding and removing values. However, that shouldn't stop us from defining a functional setter! Define a function `elem` with signature `(A) -> ((Bool) -> Bool) -> (Set<A>) -> Set<A>`, which is a functional setter that allows one to add and remove a value `a: A` to a set by providing a transformation `(Bool) -> Bool`, where the input determines if the value is already in the set and the output determines if the value should be included. | ||
*/ | ||
// TODO | ||
/*: | ||
3. Generalizing exercise #1 a bit, it turns out that all subscript methods on a type get a compiler generated key path. Use array’s subscript key path to uppercase the first favorite food for a user. What happens if the user’s favorite food array is empty? | ||
*/ | ||
// TODO | ||
/*: | ||
4. Recall from a [previous episode](https://www.pointfree.co/episodes/ep5-higher-order-functions) that the free `filter` function on arrays has the signature `((A) -> Bool) -> ([A]) -> [A]`. That’s kinda setter-like! What does the composed setter `prop(\\User.favoriteFoods) <<< filter` represent? | ||
*/ | ||
// TODO | ||
/*: | ||
5. Define the `Result<Value, Error>` type, and create `value` and `error` setters for safely traversing into those cases. | ||
*/ | ||
// TODO | ||
/*: | ||
6. Is it possible to make key path setters work with `enum`s? | ||
*/ | ||
// TODO | ||
/*: | ||
7. Redefine some of our setters in terms of `inout`. How does the type signature and composition change? | ||
*/ | ||
// TODO |
7 changes: 5 additions & 2 deletions
7
0007-setters-and-key-paths/Setters and Key Paths.playground/contents.xcplayground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<playground version='5.0' target-platform='macos'> | ||
<timeline fileName='timeline.xctimeline'/> | ||
<playground version='6.0' target-platform='macos' display-mode='rendered'> | ||
<pages> | ||
<page name='01-Episode'/> | ||
<page name='02-Exercises'/> | ||
</pages> | ||
</playground> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
...paths/Getters and Key Paths.playground/Pages/02-Exercises.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/*: | ||
# Getters and Key Paths Exercises | ||
|
||
1. Find three more standard library APIs that can be used with our `get` and `^` helpers. | ||
*/ | ||
// TODO | ||
/*: | ||
2. The one downside to key paths being _only_ compiler generated is that we do not get to create new ones ourselves. We only get the ones the compiler gives us. | ||
|
||
And there are a lot of getters and setters that are not representable by key paths. For example, the “identity” key path `KeyPath<A, A>` that simply returns `self` for the getter and that setting on it leaves it unchanged. Can you think of any other interesting getters/setters that cannot be represented by key paths? | ||
*/ | ||
// TODO | ||
/*: | ||
3. In our [Setters and Key Paths](https://www.pointfree.co/episodes/ep7-setters-and-key-paths) episode we showed how `map` could kinda be seen as a “setter” by saying: | ||
|
||
“If you tell me how to transform an `A` into a `B`, I will tell you how to transform an `[A]` into a `[B]`.” | ||
|
||
There is also a way to think of `map` as a “getter” by saying: | ||
|
||
“If you tell me how to get a `B` out of an `A`, I will tell you how to get an `[B]` out of an `[A]`.” | ||
|
||
Try composing `get` with free `map` function to construct getters that go even deeper into a structure. | ||
|
||
You may want to use the data types we defined [last time](https://github.com/pointfreeco/episode-code-samples/blob/1998e897e1535a948324d590f2b53b6240662379/0007-setters-and-key-paths/Setters%20and%20Key%20Paths.playground/Contents.swift#L2-L20). | ||
*/ | ||
// TODO | ||
/*: | ||
4. Repeat the above exercise by seeing how the free optional `map` can allow you to dive deeper into an optional value to extract out a part. | ||
|
||
Key paths even give first class support for this operation. Do you know what it is? | ||
*/ | ||
// TODO | ||
/*: | ||
5. Key paths aid us in getter composition for structs, but enums don't have any stored properties. Write a getter function for `Result` that plucks out a value if it exists, such that it can compose with `get`. Use this function with a value in `Result<User, String>` to return the user's name. | ||
*/ | ||
// TODO | ||
/*: | ||
6. Key paths work immediately with all fields in a struct, but only work with computed properties on an enum. We saw in [Algebra Data Types](https://www.pointfree.co/episodes/ep4-algebraic-data-types) that structs and enums are really just two sides of a coin: neither one is more important or better than the other. | ||
|
||
What would it look like to define an `EnumKeyPath<Root, Value>` type that encapsulates the idea of “getting” and “setting” cases in an enum? | ||
*/ | ||
// TODO | ||
/*: | ||
7. Given a value in `EnumKeyPath<A, B>` and `EnumKeyPath<B, C>`, can you construct a value in | ||
`EnumKeyPath<A, C>`? | ||
*/ | ||
// TODO | ||
/*: | ||
8. Given a value in `EnumKeyPath<A, C>` and a value in `EnumKeyPath<B, C>`, can you construct a value in `EnumKeyPath<Either<A, B>, C>`? | ||
*/ | ||
// TODO |
9 changes: 6 additions & 3 deletions
9
0008-getters-and-key-paths/Getters and Key Paths.playground/contents.xcplayground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<playground version='5.0' target-platform='macos'> | ||
<timeline fileName='timeline.xctimeline'/> | ||
</playground> | ||
<playground version='6.0' target-platform='macos' display-mode='rendered'> | ||
<pages> | ||
<page name='01-Episode'/> | ||
<page name='02-Exercises'/> | ||
</pages> | ||
</playground> |