My last question here: How to store data of a functional chain of Monoidal List?
had many great responses and one of them suggested to implement some sort of type structure in JavaScript:
const TYPE = Symbol();
const typeOf = t => x => x == null
? x
: Object.assign(x, {
[TYPE]: t
});
const isType = t => x => x == null
? false
: x[TYPE] === t;
const Foo = x => typeOf(Foo)(x);
console.log(
isType(Foo)(1) // false
, isType(Foo)([]) // false
, isType(Foo)({}) // false
, isType(Foo)(x => x) // false
, isType(Foo)(true) // false
, isType(Foo)(undefined) // false
, isType(Foo)(null) // false
);
console.log(
isType(Foo)(Foo(1)) // true
, isType(Foo)(Foo([])) // true
, isType(Foo)(Foo({})) // true
, isType(Foo)(Foo(x => x)) // true
, isType(Foo)(Foo(true)) // true
, isType(Foo)(Foo(undefined)) // false
, isType(Foo)(Foo(null)) // false
);
console.log(Foo(1) + Foo(2)); //3
While I thought this is a great idea, another member suggests this is inconsistent since Object.assign is a mutable operation and it should not be allowed in Functional Programming context.
In response, there is another idea to use Proxy instead, so I have tried to implement the similar system by myself.
The result is unfortunately very poor since Proxy
seems only to accept Object.
var target = {};
var p = new Proxy(target, {});
p.a = 37; // operation forwarded to the target
console.log(target.a); // 37. The operation has been properly forwarded
var target = 5;
var p = new Proxy(target, {});
p.a = 37; // operation forwarded to the target
console.log(target.a); // 37. The operation has been properly forwarded
I also considered to take advantage of Object.create, but does not work in similar manner of Proxy
.
Basically, I recognize this is a challenge to implement Inheritance (object-oriented programming) in functional programming with dynamic typing/ duck typing and reflection.
Therefore, I really want to make this implementation work in ES6 Proxy context.
Any great ideas? Thanks.