我在这里的最后一个问题: How to store data of a functional chain of Monoidal List?
有很多不错的响应,其中之一建议在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
虽然我认为这是个好主意,但另一位成员却认为这是不一致的,因为Object.assign是可变操作,因此在函数式编程上下文中不应允许使用。
作为回应,还有一个想法改为使用Proxy,因此我尝试自己实现类似的系统。
不幸的是,由于Proxy
似乎只接受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
“未捕获的TypeError:无法使用非对象作为目标或处理程序创建代理”
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
我还考虑过利用Object.create的优势,但是不能以类似Proxy
的方式工作。
基本上,我认识到在具有动态类型/ Inheritance (object-oriented programming)和duck typing的函数式编程中实现reflection是一个挑战。
因此,我真的很想在ES6代理上下文中实现此实现。
有什么好主意吗?谢谢。
答案 0 :(得分:0)
事实证明,
至少对于本主题而言,所有这些对于实现Reflection (computer programming)都是不必要的。
请参见下面的代码:
const selfAware = i => i[i] = i;
const isAware = i => (i[i] === i);
const I = i => (i === I) || (i == null)
? i
: selfAware(Object(i));
const amI = i => (i === I)
? true
: (i == null)
? false
: isAware(i);
const ss = I(6);
console.log(ss);
console.log(ss[ss]);
//self-similarity
console.log(ss[ss][ss]);
const obj1 = {
a: 2
};
const obj2 = I(obj1);
console.log(obj1);
console.log(obj2);
console.log(
I("Hello world!").toString() //Yes, it works!
);
console.log(I(1) + I(2)); //3
console.log(
(I) //[Function: I]
);
console.log(
(I)(I) //[Function: I]
);
console.log(
(I)(I)(I) //[Function: I]
);
console.log(
(I)(I)(I)(I) //[Function: I]
);
console.log("============================");
console.log(
amI(I) //true
, amI(1) // false
, amI([]) // false
, amI({}) // false
, amI(x => x) // false
, amI(true) // false
, amI(false) // false
, amI(undefined) // false
, amI(null) // false
);
console.log(
amI(I(I)) // true
, amI(I(1)) // true
, amI(I([])) // true
, amI(I({})) // true
, amI(I(x => x)) // true
, amI(I(true)) // true
, amI(I(false)) // true
, amI(I(undefined)) // false
, amI(I(null)) // false
);