sofs模塊,你聽說過沒有?如果沒有,很正常。今天我在閱讀rebar源碼的時候,在rebar生成熱更新文件的時候,發(fā)現(xiàn)了下面一段話:
<pre>
compare_dirs(Dir1, Dir2) ->
R1 = sofs:relation(beam_files(Dir1)),
R2 = sofs:relation(beam_files(Dir2)),
F1 = sofs:domain(R1),
F2 = sofs:domain(R2),
{O1, Both, O2} = sofs:symmetric_partition(F1, F2),
OnlyL1 = sofs:image(R1, O1),
OnlyL2 = sofs:image(R2, O2),
B1 = sofs:to_external(sofs:restriction(R1, Both)),
B2 = sofs:to_external(sofs:restriction(R2, Both)),
Diff = compare_files(B1, B2, []),
{sofs:to_external(OnlyL1), sofs:to_external(OnlyL2), Diff}.
</pre>
后來查閱了sofs的文檔,紀(jì)錄如下
(1) sofs是set of set的簡稱
(2) 既然函數(shù)在數(shù)學(xué)上定義為集合之間的映身,那么set of set能構(gòu)造類似函數(shù)的用法應(yīng)該就不奇怪了。
(3)sofs抽象映身主要用的是tuple:類似{a,1},表示a ->1,類似的有自變量域domain, 值域range,映射image相關(guān)的概念了。舉個例子
首先構(gòu)造一個關(guān)系映射
<pre>
R = sofs:relation([{b,1},{c,2},{c,3},{b,20}]).
結(jié)果為:
{'Set',[{b,1},{b,20},{c,2},{c,3}],{atom,atom}}
</pre>計算domain
<pre>
sofs:domain(R).
結(jié)果為{'Set',[b,c],atom}
</pre>計算range
<pre>
sofs:range(R).
結(jié)果為{'Set',[1,2,3,20],atom}
</pre>計算image
<pre>
1> R = sofs:relation([{b,1},{c,2},{c,3},{b,20}]).
{'Set',[{b,1},{b,20},{c,2},{c,3}],{atom,atom}}
2> D = sofs:domain(R).
{'Set',[b,c],atom}
3> sofs:image(R, D).
{'Set',[1,2,3,20],atom}
</pre>其它
<pre>
sofs:relation_to_family(R).
結(jié)果為:{'Set',[{b,[1,20]},{c,[2,3]}],{atom,[atom]}}
</pre>
用處
我覺得特別的用處,就是處理兩個properlist。properlist剛好是{k,v}結(jié)構(gòu)
比如,能夠快速找出兩個properlist中的key對應(yīng)的所有value的集合,感受下
<pre>
1> R1 = sofs:relation([{b,1},{c,2},{c,3},{b,20}]).
{'Set',[{b,1},{b,20},{c,2},{c,3}],{atom,atom}}
2> R2 = sofs:relation([{c,2},{a,3}]).
{'Set',[{a,3},{c,2}],{atom,atom}}
3> F1 = sofs:domain(R1).
{'Set',[b,c],atom}
4> F2 = sofs:domain(R2).
{'Set',[a,c],atom}
5> {O1, Both, O2} = sofs:symmetric_partition(F1, F2).
{{'Set',[b],atom},{'Set',[c],atom},{'Set',[a],atom}}
6> OnlyL1 = sofs:image(R1, O1).
{'Set',[1,20],atom}
7> OnlyL2 = sofs:image(R2, O2).
{'Set',[3],atom}
</pre>
這個就是類似于文章最開始提到的compare_dirs函數(shù)使用