UNPKG

hkt-toolbelt

Version:

Functional and composable type utilities

74 lines (73 loc) 2.27 kB
import { $, $N, Kind, NaturalNumber, Conditional, List, Function } from '..'; /** * Check whether a natural number `N` is divisible by another number `M`. * * i.e. determine whether `N % M === 0`. * * @template M - The number to divide by. * @template N - The number to check divisibility for. * * This function 'lifts' the modulo parameters (M and N) out of the pipe via * the curry and uncurry operators. * * For optimal performance, this should be implemented as a 'native' type-level * function - however this example is pedagogically valuable for demonstrating * the lifting technique. */ type DivisibleBy = $N<Kind.Curry, [ 2, $<Kind.Pipe, [ $<Kind.Uncurry, NaturalNumber.ModuloBy>, $<Conditional.Equals, 0> ]> ]>; /** * A type-level function that returns "FizzBuzz" if the input is divisible by * both 3 and 5, "Fizz" if the input is divisible by 3, "Buzz" if the input is * divisible by 5, and the input otherwise. * * This function uses the `Conditional.If` type-level function to encode an * if-then-else statement. * * @template N - The number to compute the FizzBuzz result for. * * @example * ```ts * import { $, NaturalNumberTheory } from "hkt-toolbelt" * * type R15 = $<NaturalNumberTheory.FizzBuzz, 15> // "FizzBuzz" * type R4 = $<NaturalNumberTheory.FizzBuzz, 4> // 4 * ``` */ export type FizzBuzz = $N<Conditional.If, [ $<DivisibleBy, 15>, $<Function.Constant, 'FizzBuzz'>, $N<Conditional.If, [ $<DivisibleBy, 3>, $<Function.Constant, 'Fizz'>, $N<Conditional.If, [ $<DivisibleBy, 5>, $<Function.Constant, 'Buzz'>, Function.Identity ]> ]> ]>; /** * A type-level function that returns a list of the FizzBuzz results for the * first `N` natural numbers, from 1 to `N` inclusive. * * @template N - The number of FizzBuzz results to compute. * * @example * ```ts * import { $, NaturalNumberTheory } from "hkt-toolbelt" * * // ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz"] * type R10 = $<NaturalNumberTheory.FizzBuzzSequence, 10> * ``` */ export type FizzBuzzSequence = $<Kind.Pipe, [ List.Times, $<List.Map, $<Kind.Pipe, [NaturalNumber.Increment, FizzBuzz]>> ]>; export {};