Extracting data from a function chain without arrays

  • A+

This is an advanced topic of

How to store data of a functional chain of Monoidal List?

I am pretty sure we can somehow extract data from a function chain without using an array storing data. The basic structure is :

L = a => L 

very simple, but this structure generates a list:


This may be related to What is a DList? , but this structure strictly depends on function chain only.

So, what is the way to pull out the whole values? Current achievement of mine merely pulling out the head and tail, and I don't know how to fix this.

EDIT: I forgot to mention what I try to do is

List.fold(f) / reduce(f)


So, if one choses f as Array.concat which means you can extract data as an array, but simply fold is not limited to array concatenation. and f can be add/sum etc.

So, currently, so far, to visualize the internal behavior, in a sense, I write log as f.


I must clarify more. The specification can be presented:

const f = (a) => (b) => a + b;//binary operation  A(a)(b)(f) = f(a)(b)  // a + b  A(a)(b)(c)(f) = f(f(a)(b))(c) // a + b + c 

So this is exactly

(a b c).reduce(f) 

thing, and when

f = (a) => (b) => a.concat(b) 

The result would be [a, b, c].

Array.concat is merely a member of generalized binary operations f.

At first this challenge is easy for my skill, but turned out hard and felt it's better to ask smarter coder.


const A = a => {      const B = b => (b === undefined)         ? (() => {             log("a " + a);             return A();         })()         : c => (c === undefined)             ? (() => {                 log("b " + b);                 return B()();             })()             : B;      return B;  };    A(1)(2)(3)(4)(5)(6)()  function log(m)  {     console.log((m)); //IO     return m; };


b 6 a 1 a undefined 


Given an expression like A(a)(b)(f) where f is a function, it's impossible to know whether f is supposed to be added to the list or whether it's the reducing function. Hence, I'm going to describe how to write expressions like A(a)(b)(f, x) which is equivalent to [a, b].reduce(f, x). This allows us to distinguish when the list ends depending upon how many arguments you provide:

const L = g => function (x, a) {     switch (arguments.length) {     case 1: return L(k => g((f, a) => k(f, f(a, x))));     case 2: return g((f, a) => a)(x, a);     } };  const A = L(x => x);  const xs = A(1)(2)(3)(4)(5);  console.log(xs((x, y) => x + y, 0));        // 15 console.log(xs((x, y) => x * y, 1));        // 120 console.log(xs((a, x) => a.concat(x), [])); // [1,2,3,4,5]

It works due to continuations. Every time we add a new element, we accumulate a CPS function. Each CPS function calls the previous CPS function, thereby creating a CPS function chain. When we give this CPS function chain a base function, it unrolls the chain and allows us to reduce it. It's the same idea behind transducers and lenses.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: