啊,那个我没有考虑到,其实... 写的插件还可以讲一下,所以前端给 #HTML #JavaScript
之前因为 Fx 阅读模式里面 link anchor 有 underline(decoration) 所以想加去这个的 CSS,后来才知道本来就没有...
如果有的话,可以
首先是 NSFW Template,这使用到了 HTML5 的新 <template> tag
bound 本来确实可以利用 property/reflect/proxy 来比较魔法的(而且不会担心性能问题,可以缓存)
不过有点长,而且不明显,所以这里用简单的方法
== Abbr view
这个逻辑比较简单,类似 NSFW template。因为在一些设备上不能使用 "hover" 查看 abbrev... 只好在点击时在后面插入内 abbr 的实际容了。
写入的时候先新建一个 attribute,用于记录 abbr 已经被展开,每次 switch 的时候判断一下 shown => hide、hidden => show
== Night
== Reflink Preview
== Music Player
== Footnote Xref
== Contents Tree
之前因为 Fx 阅读模式里面 link anchor 有 underline(decoration) 所以想加去这个的 CSS,后来才知道本来就没有...
如果有的话,可以
a { text-decoration: none; }
接下来简要说说几个小辅助插件了首先是 NSFW Template,这使用到了 HTML5 的新 <template> tag
bound 本来确实可以利用 property/reflect/proxy 来比较魔法的(而且不会担心性能问题,可以缓存)
不过有点长,而且不明显,所以这里用简单的方法
function bound(self, meth) { return self[meth].bind(self); }
function intoIter(xs) { var i = 0;
return function
iterator() { return (i<xs.length)? { value: xs[i++], done: false }
: {done:true}; }; }
function tryIter(xs) { if (!Symbol) return intoIter(xs); return bound(xs[Symbol.iterator](), 'next'); }
function forIter(it, f) { var xc; while (xc = it()) { f(xc.value); if (xc.done) break; } }
function args2ary(argsv) { var ary=[]; forIter(tryIter(argsv), bound(ary, 'push')); return ary; }
Function.prototype.flip = function() { var method = this; return function call() { return method.apply(method, args2ary(arguments).reverse()); }; };
Function.prototype.curry1 = function(x0) { return this.bind(this, x0); }
;
Object.prototype.lets = function(f) { return f(this); }
Function.prototype.andThen = function(g) { var f=this; return function composition(x) { return g(f(x)); }; }
foreach = tryIter.andThen(bound(forIter, 'curry1'));
function makes$_(fname) { return function(it) { return it[fname](); }; }
function makes_() {
var it = new Object();
return new Proxy(it, { get: function(t,a,p){return makes$_(a);} });
}
_ = makes_();
cssSelect = bound(document, 'querySelector');
var merges = bound(document, 'importNode').flip().curry1(true);
其中业务逻辑 部分,上面的留作代码重用function showTemplate(attr, init) {
var templates = cssSelect('template[' + attr + ']=""');
var prepend = function (nd, x) { nd.parentNode.insertBefore(x, nd); };
templates.forEach(function(x) {
var mix = merges(x.content);
if (typeof init =='function') init(mix);
prepend(x, mix);
});
}
function removeElements(cs) { cs.lets(cssSelect).each(_.delete); }
function addCSSClass(cl) { return function(e){ e.classList.add(cl); }; }
showTemplate('nsfw', addCSSClass('nsfw'));
我还得写很多.... 所以代码重用、优先划分好模块非常重要== Abbr view
这个逻辑比较简单,类似 NSFW template。因为在一些设备上不能使用 "hover" 查看 abbrev... 只好在点击时在后面插入内 abbr 的实际容了。
写入的时候先新建一个 attribute,用于记录 abbr 已经被展开,每次 switch 的时候判断一下 shown => hide、hidden => show
== Night
== Reflink Preview
== Music Player
== Footnote Xref
== Contents Tree
关于 Curry 函数
Curry 是什么呢?本来 curry 的意思是 Lambda composition (
于是 Lambda calculus 有个 currying:
这样就有一个好,因为 lambda 抽象(abstraction) 的 variable substraction 可以给一些项目提供参数,而未必要立刻『实际执行』这个函数:
可是很多函数式编程语言,比如 Haskell 是这个样子,JavaScript 就不是这个样子。
不过有 Function.prototype(参见我之前写的 LuaOOP 原型面向对象继承实现).bind
可以给指定默认参数
不过,指定就最好得一次指定完,不然很麻烦(因为 this 要传来传去的... 而且你还得手写 curry 参数的调用)
我希望这样的 curry:
开始我很 naive 地想到,好像这是在针对 accumlator(计数器一样的东西,总之就是不断被『从自己构造』)
去操作,于是非常自然地想到了 foldl, foldr (其实 foldr 的确是可以的,而且 compose = foldr (.) id,不过这里不提右递归的方法)
可是我又想到,这显然是不行的。curry1 不管怎么样至少是接受一个参数返回接剩下参数的... 这样的话毫无意义,
因为我实际上一直在提供第一个参数。
然后我就想到了,既然是要构造这么一个递归的情况(第一次填 0、每次填第 n+1 个参数)
为什么不先构造 curry 最后一个参数的情况,然后串起来呢?这样不就可以了?
不过这当然是没有那么简单的,因为 bind 是 left-to-right,然后手动调用也得拿到每一个 curry 的参数
不过我们可以用 effect. 创建的时候弄一个 array 每层去 push 一下就好了
算了还是右递归 bind 吧(当然自己写也可以,就是给左边填一个参数返回右边剩下的)... 用 effect 没必要
#JavaScript #FP #Haskell
Curry 是什么呢?本来 curry 的意思是 Lambda composition (
f.g = \args -> f (g args) ) 很难去接受一些『多参数函数』(要不然处理起来就很迷人...)于是 Lambda calculus 有个 currying:
\x y. x = \x. \y. x (原本一个多参数的 lambda 现在变成了多个单参数 lambda 的组合)这样就有一个好,因为 lambda 抽象(abstraction) 的 variable substraction 可以给一些项目提供参数,而未必要立刻『实际执行』这个函数:
add = \a. \b. (a + b)它可以提供『不能重写』的参数默认值(因为那里 2 就是立即值或者 UpValue 了,递归的时候这个东西不是参数的)
add2 = add 2 = \b. (2 + b)
add2 1 = 3
可是很多函数式编程语言,比如 Haskell 是这个样子,JavaScript 就不是这个样子。
不过有 Function.prototype(参见我之前写的 LuaOOP 原型面向对象继承实现).bind
可以给指定默认参数
不过,指定就最好得一次指定完,不然很麻烦(因为 this 要传来传去的... 而且你还得手写 curry 参数的调用)
我希望这样的 curry:
var puts = bound(matrix, 'putXY').curry()然后我早上赖床(逃跑)的时候就在想,该怎么实现这个多参数 curry 呢?
var puts00 = puts(0)(0)
puts00('0,0')
开始我很 naive 地想到,好像这是在针对 accumlator(计数器一样的东西,总之就是不断被『从自己构造』)
去操作,于是非常自然地想到了 foldl, foldr (其实 foldr 的确是可以的,而且 compose = foldr (.) id,不过这里不提右递归的方法)
可是我又想到,这显然是不行的。curry1 不管怎么样至少是接受一个参数返回接剩下参数的... 这样的话毫无意义,
因为我实际上一直在提供第一个参数。
然后我就想到了,既然是要构造这么一个递归的情况(第一次填 0、每次填第 n+1 个参数)
为什么不先构造 curry 最后一个参数的情况,然后串起来呢?这样不就可以了?
不过这当然是没有那么简单的,因为 bind 是 left-to-right,然后手动调用也得拿到每一个 curry 的参数
不过我们可以用 effect. 创建的时候弄一个 array 每层去 push 一下就好了
算了还是右递归 bind 吧(当然自己写也可以,就是给左边填一个参数返回右边剩下的)... 用 effect 没必要
function _curryN(f, ff, n) {
if (n == 0) return ff;
return function nextDefault(x_)
{ return _curryN(f, ff.bind(f, x_), n-1); };
}
Function.prototype.curryN(n) { return _curryN(this, this, n); }
总之递归构造数据还是... 应该是符合直觉好 吧...#JavaScript #FP #Haskell