let a = b in cは意味論的には(fun (a) -> c)(b)と等価
たまたまみかけた
より、まず「副作用」の使い方が変な気がしますがそれは置いといて、erlangでは、ガードでかける式が限定されるのは初めて知ったので勉強になりました。
- http://www.erlang.org/doc/reference_manual/expressions.html#6.24 (guard expressionのとこ)
あまりerlangには詳しくないけど、関数型言語での上記のLISPでの式と等価な式を想定するのであれば、ifではなくandのままでいけるだろうし、let式がなければとfunとその適用で代用するのが妥当と思います。
isMirror(L) -> LENGTH = length(L), (LENGTH rem 2 == 0) and (fun (MID) -> lists:sublist(L, MID) == lists:reverse(lists:sublist(L, MID+1, LENGTH - MID)) end)(trunc(LENGTH / 2)).
もしくはfunの中でも局所変数をおけるので、
isMirror(L) -> LENGTH = length(L), (LENGTH rem 2 == 0) and (fun () -> MID = trunc(LENGTH / 2), lists:sublist(L, MID) == lists:reverse(lists:sublist(L, MID+1, LENGTH - MID)) end)().
というかんじに長さも(List系関数名をのぞけば)LISP版のコードと差がないと思います。
lists:splitをつかえばもう少し楽な気もする:
isMirror(L) -> Len = length(L), (Len rem 2 == 0) and (fun () -> {Left, Right} = lists:split(Len div 2, L), Left == lists:reverse(Right) end)().
偶数判定もいらないか
isMirror(L) -> {Left, Right} = lists:split(length(L) div 2, L), Left == lists:reverse(Right).
というかlengthもsplitもiterationしてるとして、要素の比較が単純だとすれば、reverseして比較のほうが速いかもしれない:
isMirror(L) -> L == lists:reverse(L).