如何在Erlang中包装长函数头?

时间:2014-11-29 12:06:30

标签: erlang

如何以一种可以被认为是"惯用的"在Erlang?

我很欣赏这种情况本身就是一种代码味道,但我真的没有其他选择,因为我正在写一个有趣的传递给 ets:fun2ms / 1 而且我不想要一个超过80个字符的行。这是原始功能:

Matcher = ets:fun2ms(
    fun({Id, Orig2, _, Kg, _, _, Status}) when Orig1 == Orig2, Kg =< MaxKg, Status == pending ->
        {Id, Kg}
    end
)

包装第2行的推荐方法是什么?

TIA!

2 个答案:

答案 0 :(得分:1)

Matcher =
    ets:fun2ms(fun({Id, Orig2, _, Kg, _, _, Status})
                   when Orig1 == Orig2,
                        Kg =< MaxKg,
                        Status == pending ->
                            {Id, Kg}
                end)

或者

Selector = fun({Id, Orig2, _, Kg, _, _, Status})
               when Orig1 == Orig2,
                    Kg =< MaxKg,
                    Status == pending ->
                        {Id, Kg}
           end,
Matcher = ets:fun2ms(Selector)

或者其他任何使用短语的方式,以及语义上不同的组件,如果每个短语都是明确的,并且以明显和可读的方式脱颖而出。时髦的一个几乎总是end在一个漫长的lambda的末尾 - 我从来没有找到一个令人满意的方式来处理它,除了不写一个lambda而是写一个顶级函数

如果你有 lot 的选择条件(或者一次修改它们的一个方面,这样声明基函数,然后将闭包定义为它们上面的lambdas是有意义的),但是,写作一个模块只是一个选择条件库,有时可以简化代码并完全防止长lambdas和end的怪异。你只需要决定什么对你有意义。就像他们总是在埃兰说的那样:首先让它发挥作用,然后让它美丽。只有当你发现自己遇到问题时才能加快速度,因为“漂亮”通常会偶然地解决速度问题。

OTOH,在Erlang代码中有一些几乎无法解读的内联lambda定义(特别是在GitHub上),所以它不像你在丑陋的部门中超过任何人(即使你做了几只眼睛流血)。

答案 1 :(得分:0)

您的大部分线路长度来自防护功能。使用函数头比较惯用:

Matcher = ets:fun2ms(
    fun({Id, Orig1, _, Kg, _, _, pending}) when Kg =< MaxKg ->
        {Id, Kg}
    end
)

我通常会避免在守卫中使用平等,而且我发现上述内容更清楚。