✨ Add an exercise 0 for pipe and flow
This commit is contained in:
parent
e33814cf3b
commit
27f8c00210
3 changed files with 120 additions and 0 deletions
48
src/exo0/exo0.test.ts
Normal file
48
src/exo0/exo0.test.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { isOddF, isOddP, next, next3 } from './exo0';
|
||||
|
||||
describe('exo0', () => {
|
||||
describe('isOddP', () => {
|
||||
it('should return true if the provided number is odd', () => {
|
||||
const oddValue = 1;
|
||||
|
||||
expect(isOddP(oddValue)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if the provided number is even', () => {
|
||||
const oddValue = 2;
|
||||
|
||||
expect(isOddP(oddValue)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isOddF', () => {
|
||||
it('should return true if the provided number is odd', () => {
|
||||
const oddValue = 1;
|
||||
|
||||
expect(isOddF(oddValue)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if the provided number is even', () => {
|
||||
const oddValue = 2;
|
||||
|
||||
expect(isOddF(oddValue)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('next', () => {
|
||||
it('should return the correct next element in the Collatz sequence', () => {
|
||||
expect(next(4)).toBe(2);
|
||||
expect(next(2)).toBe(1);
|
||||
expect(next(1)).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('next3', () => {
|
||||
it('should return the correct element in the Collatz sequence 3 steps ahead', () => {
|
||||
expect(next3(12)).toBe(10);
|
||||
expect(next3(10)).toBe(8);
|
||||
expect(next3(8)).toBe(1);
|
||||
expect(next3(1)).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
71
src/exo0/exo0.ts
Normal file
71
src/exo0/exo0.ts
Normal file
|
@ -0,0 +1,71 @@
|
|||
// `fp-ts` training introduction
|
||||
// Composing computations with `pipe` and `flow`
|
||||
|
||||
// Functional programming is all about composing small functions together like
|
||||
// lego bricks to build more and more complex computations.
|
||||
//
|
||||
// Strictly speaking, composing two functions `f` and `g` means applying the
|
||||
// result of the first one to the second one. By applying this composition
|
||||
// over and over you can chain multiple functions together.
|
||||
//
|
||||
// The `fp-ts` library provides to helpers to do that:
|
||||
// - `pipe` which first needs to be fed a value to start the pipe and then
|
||||
// any number of functions to be applied sequentially.
|
||||
// - `flow` which is the same thing but were we do not have to provide the
|
||||
// first value. It will then return a function which will expect that value
|
||||
// to be provided
|
||||
//
|
||||
// ```ts
|
||||
// flow(f, g, h) === x => pipe(x, f, g, h)
|
||||
// pipe(x, f, g, h) === flow(f, g, h)(x)
|
||||
// ```
|
||||
//
|
||||
// NOTES:
|
||||
// - `flow(f) === f`
|
||||
// - `pipe(x, f) === f(x)`
|
||||
|
||||
import { unimplemented } from '../utils';
|
||||
|
||||
export const isEven = (value: number) => value % 2 === 0;
|
||||
|
||||
export const not = (value: boolean) => !value;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// PIPE & FLOW //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// For this exercise each function needs to be implemented using both forms:
|
||||
// - a `pipe` implementation (P suffix)
|
||||
// - a `flow` implementation (F suffix)
|
||||
|
||||
// Using only the two helpers `isEven` and `not` at the top of this file (and
|
||||
// `pipe` or `flow`), write the function `isOdd` that checks if a number is
|
||||
// odd.
|
||||
|
||||
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
|
||||
//
|
||||
// Below is the functional equivalent of the control flow statement if-else.
|
||||
|
||||
export const ifThenElse = <A>(onTrue: () => A, onFalse: () => A) => (
|
||||
condition: boolean,
|
||||
) => (condition ? onTrue() : onFalse());
|
||||
|
||||
// Using `pipe` the function that computes the next step in the Collatz
|
||||
// sequence.
|
||||
|
||||
export const next: (value: number) => number = unimplemented;
|
||||
|
||||
// Using only `flow` and `next`, write the function that for any given number
|
||||
// a_n from the Collatz sequence, returns the number a_n+3 (ie. the number
|
||||
// three steps ahead in the sequence).
|
||||
|
||||
export const next3: (value: number) => number = unimplemented;
|
1
src/exo0/index.ts
Normal file
1
src/exo0/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './exo0';
|
Reference in a new issue