?

Log in

No account? Create an account

немного ерланга под утро - mclap — ЖЖ

авг. 13, 2011

06:59 am - немного ерланга под утро

Previous Entry Поделиться Next Entry

is_char(C) when C < 0; C > 255 -> false;
is_char(_) -> true.

%% (c) mclap 
strip_html(HTML) ->
	case is_list(HTML) of
		true -> case lists:all(fun(V) -> is_char(V) end, HTML) of
			true -> HTML;
			false -> lists:foldl(fun(X, AccIn) -> 
					strip_html(X) ++ AccIn
					end, "", HTML)
			end;
		false -> case tuple_size(HTML) of
			2 -> strip_html(element(2,HTML));
			_ -> strip_html(element(2,HTML)) ++
				 strip_html(element(3,HTML))
			end
end.

test() ->
	strip_html(example_data()).

Еще немного прекрасного из черновиков:
decode2(<<1:1, V:7, Rest/binary>>) ->
        {S, L} = decode2(Rest),
        {S bsl 7 + V, L+1};
decode2(<<0:1, V:7, _>>) ->
        { V, 1 };
decode2(<<0:1, V:7>>) ->
        { V, 1 }.

let rec decode = function
    | h::t when (h<128) -> h
    | h::t -> ((decode t) lsl 7) + (h land 127)

Аналогичный куску на Ocaml код на C занимает не менее 5 строк, а с комментариями и прочими проверками аргументов - уже экран (правда не в черновике, а в работе ;-)

Tags: ,

Comments:

[User Picture]
From:lionet
Date:Август 13, 2011 03:10 am
(Link)
Erlang: так короче и на одну ошибку (болд) меньше:

is_char(C) -> C >= 0 andalso C =< 255.

strip_html([_|_]) ->
    case lists:all(fun is_char/1, HTML) of
        true -> HTML;
        false -> lists:foldr(fun(X, AccIn) -> 
					strip_html(X) ++ AccIn
					end, "", HTML)
			end;
    end;
strip_html({_, HTML}) ->
    strip_html(HTML);
strip_html({_, HTML1, HTML2}) ->
    strip_html(HTML1) ++ strip_html(HTML2).
end.

(Ответить) (Thread)
[User Picture]
From:mclap
Date:Август 13, 2011 06:00 am
(Link)
Сигнатуре для списков чего-то не хватает явно - объявления HTML:
strip_html(HTML=[_|_]) ->
    case lists:all(fun is_char/1, HTML) of

Что после 4-х лет повседневного использования HTML выглядит символично %-)
(Ответить) (Parent) (Thread)
[User Picture]
From:mclap
Date:Август 13, 2011 06:05 am
(Link)
кстати, почему foldr ?
(Ответить) (Parent) (Thread)
[User Picture]
From:lionet
Date:Август 13, 2011 03:41 pm
(Link)
Foldl сворачивает с головы к концу списка. В итоге на последнем элементе списка в аккумуляторе будет почти весь документ, а вот в strip_html попадет последний его элемент. А потом раз — и ты последний элемент ставишь в начало результирующего документа. Понятно что будет? Текст наизнанку будет.

Менять аргументы у ++ местами тоже нельзя в foldl, иначе получится квадратичный алгоритм. Итого — foldr: и текст не наизнанку, и сложность O(N).
(Ответить) (Parent) (Thread)
[User Picture]
From:mclap
Date:Август 13, 2011 06:10 am
(Link)
с чем, интересно, связан запрет на использовании в fun/if guard локальных функций ? а для case его нет. странно.
(Ответить) (Parent) (Thread)
[User Picture]
From:lionet
Date:Август 13, 2011 03:43 pm
(Link)
Какой запрет? Я не понимаю, о чем ты.
(Ответить) (Parent) (Thread)
[User Picture]
From:mclap
Date:Август 13, 2011 06:59 pm
(Link)
В моем случае это было что-то вроде:
is_char(C) -> C >= 0 andalso C =< 255.

test(V) when is_char(V) ->
        V.
test() ->
        test(10).
9> c(e2).
./e2.erl:9: call to local/imported function is_char/1 is illegal in guard
./e2.erl:7: Warning: function is_char/1 is unused
error


Первый вариант strip_html содержал наивную сигнатуру с when is_string(...) ->. Впрочем, ответ нашел в http://www.erlang.org/doc/reference_manual/expressions.html#id78951, "7.24 Guard expressions".
(Ответить) (Parent) (Thread)