Как называется колесо от FP, которое я пытаюсь изобрести? (см. код) - PullRequest
0 голосов
/ 31 августа 2018

Желаемый конечный машинописный код:

transform(input)(transformation1)(transformation2)(...
// input is any data, e.g. string or object
// transformationX should be a transforming function

Я уже написал код ниже, и мне кажется, что я изобрел колесо, то есть что-то подобное должно быть уже реализовано в FP, но я не знаю, как оно называется. Кто-нибудь может сказать, какой инструмент из https://gcanti.github.io/fp-ts/ можно использовать вместо него?

type Transformer = (transformation: Transformation) => Transformer
type Transformation = (input: object) => Transformer

const TranformerCreator = (input: object): Transformer
    => (transformation: Transformation): Transformer
        => transformation(input)

const transform: Transformation = (input: object) => {
    return TranformerCreator(input)
}

const transformation1: Transformation = (input: object) => {
    // do sometging with input

    return TranformerCreator(input)
}

1 Ответ

0 голосов
/ 01 сентября 2018

Это монада продолжения , где приложение функции используется как операция bind

const cont = x =>
  k => k (x)
  
const add1 = x =>
  cont (x + 1)
  
const double = x =>
  cont (x * 2)
  
const square = x =>
  cont (x * x)
  
cont (2) (add1) (double) (square) (console.log)
// 36
// 2 -> add1 -> 3 -> double -> 6 -> square -> 36

Вот еще одна кодировка, которая может помочь понять, как она работает. Вместо использования приложения функции для привязки используются явные функции bind и unit. Примечание: «связывание» здесь не связано с Function.prototype.bind и относится к двоичной операции монады

class Cont
{ constructor (run)
  { this.run = run
  }
  
  bind (f)
  { return new Cont (k => this.run (x => f (x) .run (k)))
  }
  
  static unit (x)
  { return new Cont (k => k (x))
  }
}

const add1 = x =>
  Cont.unit (x + 1)
  
const double = x =>
  Cont.unit (x * 2)
  
const square = x =>
  Cont.unit (x * x)
  
Cont.unit (2)
  .bind (add1)
  .bind (double)
  .bind (square)
  .run (console.log) // 36
...