Tue, Jan 26, 2021
Y Combinator学习总结 scheme版本Y组合子
(define Y (lambda (le) ((lambda (f) (f f)) (lambda (f) (le (lambda (x) ((f f) x))))))) 直接翻译为erlang代码
Y = fun(M) -> (fun(F) -> F(F) end)( fun(F) -> M(fun(X) -> (F(F))(X) end) end ) end. 这样看起来不怎么清晰,抽取函数体,定义为变量,再带入fun(F) -> F(F) end即获得
Y = fun(M) -> G = fun (F) -> M(fun(X) -> (F(F))(X) end) end, G(G) end. Y组合子是用于lambda演算中实现递归逻辑的,即是可以实现匿名函数的递归调用。原理就是fixed-point combinator,不动点组合子。高阶函数f的不动点是另一个函数 g,使得f(g) = g。那么不动点算子是任何函数fix使得对于任何函数f都有f(fix(f)) = fix(f)。这样就可以实现匿名函数把自己算出来,从而间接调用会自己,实现递归了。
Fac = fun (F) -> fun (0) -> 1; (N) -> N * F(N-1) end end.
Mon, Jan 25, 2021
#用erlang实现的简易名字搜索
游戏中一般都会提供根据输入的字符搜索家族,玩家出来。以往的项目要么只能全匹配,要么是通过mysql的模糊搜索来查询的。新项目中全匹配明显不符合要求,而项目设计又不想为了这个功能而加入mysql来增加复杂度,那么剩下的就只有用erlang来实现搜索了。
想当然的就会想到用mnesia来实现,但mnesia只是个KV,功能并不足以实现需求。自己实现一个完整模糊搜索工作量也不小,还好策划的需求并不复杂。
搜索出来的结果只需几十条用于显示 不需要分页显示 为了快速的完成,因此决定搜索只支持从前往后的匹配。因为名字本来就有限制输入特殊符号,以及长度限制,所以对于玩家来说也不会有太大的影响。结合需求以及这些限制,整体设计方案就变得简单许多了。
接下来就是构建索引,首先将名字abc,拆成a,ab,abc,然后将它们都指向abc这个ID。搜索时根据玩家的输入如ab,那么就可以很快的直接找出ab,abc,abd,abcd的对应ID了。删除索引也是如此,生成名字索引列表,然后直接删除表项即可。
搜索的目的就是想找到自己查询的信息,但根据前面的设计,当玩家完整输入一个完整名字时,有可能因为该索引值对应的ID列表长度已超出显示上限,而没能返回给玩家。所以需要给全匹配的名字增加一个权重,搜索时优先返回权重高的名字回来,这样整体的搜索结果就可以满足要求了。而至于存储,使用ets的bag类型就最方便了。因为设计方案简单,整体核心代码也就50行左右。
前几天看了下代码还是可以继续优化的,因为显示就20条,就没必要把全部名字都索引了,我只需要保存同个索引的最近40条左右即可。删除时只找权重低的,即非全匹配名字的索引来删。这样可以大大的减少索引量,而且搜索时mnesia:dirty_read不会因返回大量数据而耗费了内存。
方案虽然简单,但缺点也很明显。只能从前往后搜索,对于名字开头有特殊符号的,玩家也只能自己输入,才能搜索,而这些符号一般都不太好找。但能花很少的时间,满足80%的功能需求,还是可以尝试下的。
Sat, Jan 23, 2021
#Erlang比特语法
Value:Size/TypeSpecifierList
The Size or the TypeSpecifier, or both, can be omitted. Thus, the following variants are allowed:
Value Value:Size Value/TypeSpecifierList Default values are used when specifications are missing. The default values are described in Defaults.
The Value part is any expression, when used in binary construction. Used in binary matching, the Value part must be a literal or a variable. For more information about the Value part, see Constructing Binaries and Bitstrings and Matching Binaries.
Fri, Jan 22, 2021
#Mnesia使用注意事项
index_read会锁住全表,并严重阻塞写操作,使得读写较为平均的并发受到很大限制。如果需要索引,那么存两张表,一张专门用于索引,索引与主键一一映射 mnesia事务内部的操作应越短越好,因为访问的记录产生的锁只在事务提交时释放
Wed, Jan 20, 2021
#Windows下设置git bash
首先生成ssh key
ssh-keygen -t rsa -C "xxxxx@xxxxx.com" 查看公钥,添加到外部仓库中(git@OSC, github)
cat ~/.ssh/id_rsa.pub 在git bash启动时添加执行脚本,vi ~/.bashrc,输入
eval `ssh-agent` ssh-add 重启git bash,此时会提示输入密码,以后的git操作将不再需要输密码了
Sun, Jan 10, 2021
rongtou的编程感想记录