💬 Fix some wording (#25)
* 💬 Fix some wording * Update src/exo1/exo1.ts Co-authored-by: Hugo Saracino <hugo@inato.com> * 💬 Be more precise Co-authored-by: Hugo Saracino <hugo@inato.com>
This commit is contained in:
parent
080bbec544
commit
480e063d8c
6 changed files with 22 additions and 16 deletions
|
@ -8,6 +8,12 @@ tests.
|
|||
|
||||
But first, it is essential to understand why we are using `fp-ts`. I suggest you read this [article](https://medium.com/inato/our-journey-to-functional-programing-36854a370de1) and then start the exercises.
|
||||
|
||||
After cloning the repository, setup the project by running
|
||||
|
||||
```sh
|
||||
$ yarn
|
||||
```
|
||||
|
||||
To run the tests, simply run
|
||||
|
||||
```sh
|
||||
|
|
|
@ -46,13 +46,13 @@ export const isOddP: (value: number) => boolean = unimplemented;
|
|||
|
||||
export const isOddF: (value: number) => boolean = unimplemented;
|
||||
|
||||
// The Collatz conjecture: https://en.wikipedia.org/wiki/Collatz_conjecture
|
||||
//
|
||||
// We will write a function that for any given number, computes the next
|
||||
// one according to the following rules:
|
||||
// - if n is even => divide it by two
|
||||
// - if n is odd => triple it and add one
|
||||
//
|
||||
// This sequence is the object of The Collatz conjecture: https://en.wikipedia.org/wiki/Collatz_conjecture
|
||||
//
|
||||
// Below is the functional equivalent of the control flow statement if-else.
|
||||
|
||||
export const ifThenElse =
|
||||
|
@ -60,7 +60,7 @@ export const ifThenElse =
|
|||
(condition: boolean) =>
|
||||
condition ? onTrue() : onFalse();
|
||||
|
||||
// Using `pipe`, write the function that computes the next step in the Collatz
|
||||
// Using `pipe` and `ifThenElse`, write the function that computes the next step in the Collatz
|
||||
// sequence.
|
||||
|
||||
export const next: (value: number) => number = unimplemented;
|
||||
|
|
|
@ -17,7 +17,7 @@ export const divide = (a: number, b: number): number => {
|
|||
// OPTION //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Write the safe version of `divide` with signature:
|
||||
// Write the safe version (meaning it handles the case where b is 0) of `divide` with signature:
|
||||
// safeDivide : (a: number, b: number) => Option<number>
|
||||
//
|
||||
// HINT: Option has two basic contructors:
|
||||
|
@ -67,7 +67,7 @@ export const asyncDivide = async (a: number, b: number) => {
|
|||
return a / b;
|
||||
};
|
||||
|
||||
// Write the safe version of `divide` with signature:
|
||||
// Write the safe version of `asyncDivide` with signature:
|
||||
// asyncSafeDivideWithError : (a: number, b: number) => TaskEither<DivideByZeroError, number>
|
||||
//
|
||||
// HINT: TaskEither has a special constructor to transform a Promise<T> into
|
||||
|
|
|
@ -95,7 +95,7 @@ export const invalidTargetFailure = Failure.builder(
|
|||
// EITHER //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// The next three function take the currently targeted unit by the player and
|
||||
// The next three functions take the unit currently targeted by the player and
|
||||
// return the expected damage type if appropriate.
|
||||
//
|
||||
// If no unit is selected, it should return
|
||||
|
@ -134,7 +134,7 @@ export const checkTargetAndShoot: (
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// The next three function take a `Character` and optionally return the
|
||||
// expected damage type if the unit match the expected character type.
|
||||
// expected damage type if the unit matches the expected character type.
|
||||
//
|
||||
// HINT: These functions represent the public API. But it is heavily
|
||||
// recommended to break those down into smaller private functions that can be
|
||||
|
|
|
@ -100,11 +100,11 @@ export interface Person {
|
|||
}
|
||||
|
||||
export const sortPersonsByName: (
|
||||
person: ReadonlyArray<Person>,
|
||||
persons: ReadonlyArray<Person>,
|
||||
) => ReadonlyArray<Person> = unimplemented;
|
||||
|
||||
export const sortPersonsByAge: (
|
||||
person: ReadonlyArray<Person>,
|
||||
persons: ReadonlyArray<Person>,
|
||||
) => ReadonlyArray<Person> = unimplemented;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -117,5 +117,5 @@ export const sortPersonsByAge: (
|
|||
// HINT: Take a look at `readonlyArray.sortBy`
|
||||
|
||||
export const sortPersonsByAgeThenByName: (
|
||||
person: ReadonlyArray<Person>,
|
||||
persons: ReadonlyArray<Person>,
|
||||
) => ReadonlyArray<Person> = unimplemented;
|
||||
|
|
|
@ -97,13 +97,13 @@ export const getCountryCurrencyOfOptionalCountryCode: (
|
|||
optionalCountryCode: Option<CountryCode>,
|
||||
) => Task<Option<Currency>> = unimplementedAsync;
|
||||
|
||||
// Let's now use this function in our naive implementation's pipe to how it
|
||||
// Let's now use this function in our naive implementation's pipe to see how it
|
||||
// improves it.
|
||||
// Implement `giveCurrencyOfCountryToUser` below so that it returns a
|
||||
// `Task<Option<Currency>>`
|
||||
//
|
||||
// HINT: You should be able to copy the pipe from naiveGiveCurrencyOfCountryToUser
|
||||
// and make only few updates of it
|
||||
// and make only few updates of it. `task.chain` helper may be usefull.
|
||||
|
||||
export const giveCurrencyOfCountryToUser: (
|
||||
countryNameFromUserMock: string,
|
||||
|
@ -117,7 +117,7 @@ export const giveCurrencyOfCountryToUser: (
|
|||
// TRAVERSING ARRAYS //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Let's say we want to ask multiple countries to the user. We'll have an array
|
||||
// Let's say we want to ask the user to provide multiple countries. We'll have an array
|
||||
// of country names as `string` and we want to retrieve the country code of each.
|
||||
// Looks pretty easy:
|
||||
export const getCountryCodeOfCountryNames = (
|
||||
|
@ -207,9 +207,9 @@ export const performAsyncComputationInSequence: (
|
|||
// say `Task`) and 'invert' the container (to get a `Task<Option>` instead of a
|
||||
// `Option<Task>` in our example)
|
||||
// Sometimes, you just have two nested containers that you want to 'invert'. It
|
||||
// can be because both order of container are meaningful (like `Either<Option>`
|
||||
// and `Option<Either>`) of because you got them from an external api, as
|
||||
// examples.
|
||||
// can be because the order of containers is meaningful (like `Either<Option>`
|
||||
// and `Option<Either>`) because you got them from an external api, as
|
||||
// in the examples.
|
||||
// In that case, what you need is `sequence`, which you can find in the modules
|
||||
// that have `traverse`.
|
||||
//
|
||||
|
|
Reference in a new issue