Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pipe #20747

Open
kadensharpin opened this issue Dec 15, 2022 · 2 comments · May be fixed by #20748
Open

Pipe #20747

kadensharpin opened this issue Dec 15, 2022 · 2 comments · May be fixed by #20748
Labels
new-challenge Propose a new challenge, a PR will be auto generated

Comments

@kadensharpin
Copy link
Contributor

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

difficulty: medium
title: Pipe
tags: array

Question

Implement a type-safe version of the function composition pipe() function. pipe() takes a series of functions as an argument and returns a function with the arguments of the first and the return-type of the last.

A simple JS implementation would be:

const pipe = (...fns: (() => any)[]) => (...args: any[]) => fns.reduce((p, c) => [c.apply(null, p)], args);
  
const stringToArray = (str: string) => Array.from(str);
const reverseArray = (arr: any[]) => arr.reverse();
const arrayToString = (arr: string[]) => arr.join("");

const reverseString = pipe(stringToArray, reverseArray, arrayToString); // should be (str: string) => string
// same as (str: string) => arrayToString(reverseArray(stringToArray(str)))

It creates a pipeline, hence the name. Each function passes its return value to the next function. Running reverseString(str) would result in:

stringToArray(str) -> reverseArray(arr) -> arrayToString(arr)

Template

declare function pipe(...fns: any[]): any;

Test Cases

import type { Equal, Expect } from '@type-challenges/utils'

const getString = () => "Hello World!";
const reverseString = (str: string) => Array.from(str).reverse().join("");
const getLength = (str: string) => str.length;
const addTen = (n: number) => n + 10;
const timesByTwo = (n: number) => n * 2;

const case1 = pipe();
const case2 = pipe(getString);
const case3 = pipe(getString, reverseString);
const case4 = pipe(reverseString);
const case5 = pipe(getString, reverseString, getLength, addTen, timesByTwo);
const case6 = pipe(addTen, timesByTwo);

type cases = [
  Expect<Equal<typeof case1, Expected1>>,
  Expect<Equal<typeof case2, Expected2>>,
  Expect<Equal<typeof case3, Expected3>>,
  Expect<Equal<typeof case4, Expected4>>,
  Expect<Equal<typeof case5, Expected5>>,
  Expect<Equal<typeof case6, Expected6>>
]

pipe(
  getString,
  // @ts-expect-error
  addTen
);
pipe(
  addTen,
  // @ts-expect-error
  getLength
);
pipe(
  timesByTwo,
  addTen,
  // @ts-expect-error
  reverseString
);

type Expected1 = () => void;
type Expected2 = () => string;
type Expected3 = () => string;
type Expected4 = (str: string) => string;
type Expected5 = () => number;
type Expected6 = (n: number) => number;
@kadensharpin kadensharpin added the new-challenge Propose a new challenge, a PR will be auto generated label Dec 15, 2022
@github-actions github-actions bot linked a pull request Dec 15, 2022 that will close this issue
@github-actions
Copy link
Contributor

#20748 - Pull Request updated.

2022-12-15T16:55:04.415Z Preview in Playground

github-actions bot pushed a commit that referenced this issue Dec 15, 2022
@kadensharpin
Copy link
Contributor Author

Solution: Playground

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-challenge Propose a new challenge, a PR will be auto generated
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant