Erlang의 풍부한 표현 방법을 보여주기 위한 간단한 예제를 만들었다.
lists:map에 전달하는 첫번째 파라미터(함수) 부분의 표현 방법을 보면 된다.
by_... function은 리스트를 입력받아 각 요소가 홀수인지 짝수인지 판별한다 (에러 처리 포함).
기본적으로 유념해야 할 것은,
자세한 것은 코드 참조.
happy hackin'
lists:map에 전달하는 첫번째 파라미터(함수) 부분의 표현 방법을 보면 된다.
by_... function은 리스트를 입력받아 각 요소가 홀수인지 짝수인지 판별한다 (에러 처리 포함).
@spec (by_...([integer() | any()]) -> [odd | even | error].
기본적으로 유념해야 할 것은,
- if는 guard expression을 사용하고, case는 pattern matching을 사용한다.
- if는 마지막에 true, case는 마지막에 underscore(_) 또는 Any를 사용하여 default(catch all) 조건을 만든다.
- guard의 and는 comma(,)이고, or는 semicolon(;)이다.
자세한 것은 코드 참조.
%%% -*- mode: erlang; tab-width: 4; indent-tabs-mode: nil -*-
%%%-------------------------------------------------------------------
%%% File : expressions.erl
%%% Author : M.W. Park <manywaypark@gmail.com>
%%% Description : an erlang example (to explain expressions)
%%% ref: http://www.erlang.org/doc/reference_manual/expressions.html
%%%
%%% Created : 2011-09-22 목요일 by M.W. Park
%%%-------------------------------------------------------------------
-module(expressions).
%% -export([]).
%% -import(, []).
-compile(export_all).
%% using guard inside 'if'
by_if(L) when is_list(L) ->
lists:map(fun(X) ->
if
is_integer(X),
X rem 2 =:= 0 -> even;
is_integer(X) -> odd;
true -> error
end
end,
L).
%% nested 'case'
by_case(L) when is_list(L) ->
lists:map(fun(X) ->
case is_integer(X) of
true ->
case X rem 2 of
0 -> even;
_ -> odd
end;
_ -> error
end
end,
L).
%% 'case' w/ guards
by_case_with_guard(L) when is_list(L) ->
lists:map(fun(X) ->
case X of
_ when is_integer(X),
X rem 2 =:= 0 -> even;
_ when is_integer(X) -> odd;
_ -> error
end
end,
L).
%% 'case' w/ exception
%% 'rem' operator may throw an exception.
by_case_with_ex(L) when is_list(L) ->
lists:map(fun(X) ->
try
case X rem 2 of
0 -> even;
_ -> odd
end
catch
_:_ -> error
end
end,
L).
%% pattern matching functions
'what?'(X) when is_integer(X), X rem 2 =:= 0 ->
even;
'what?'(X) when is_integer(X) ->
odd;
'what?'(_) ->
error.
%% passing function name as a parameter
by_passing_fun(L) when is_list(L) ->
lists:map(fun 'what?'/1, L).
%% anonymous function w/ guards
by_anonymous_fun(L) when is_list(L) ->
lists:map(fun(X) when is_integer(X),
X rem 2 =:= 0 -> even;
(X) when is_integer(X) -> odd;
(_) -> error
end,
L).
%% mixture of anonymous function w/ a guard and 'case'
by_mix(L) when is_list(L) ->
lists:map(fun(X) when is_integer(X) ->
case X rem 2 of
0 -> even;
_ -> odd
end;
(_) -> error
end,
L).
%%%-------------------------------------------------------------------
%%% Unit Tests
%%%-------------------------------------------------------------------
-include_lib("eunit/include/eunit.hrl").
-define(BASIC(FunName), ?_assertEqual([odd, even], FunName(lists:seq(1, 2)))).
-define(ERROR(FunName), ?_assertEqual([error, error], FunName([0.1, atom]))).
by_if_test_() ->
[
?BASIC(by_if),
?ERROR(by_if)
].
by_case_test_()->
[
?BASIC(by_case),
?ERROR(by_case)
].
by_case_with_guard_test_() ->
[
?BASIC(by_case_with_guard),
?ERROR(by_case_with_guard)
].
by_case_with_ex_test_() ->
[
?BASIC(by_case_with_ex),
?ERROR(by_case_with_ex)
].
by_passing_fun_test_() ->
[
?BASIC(by_passing_fun),
?ERROR(by_passing_fun)
].
by_anonymous_fun_test_() ->
[
?BASIC(by_anonymous_fun),
?ERROR(by_anonymous_fun)
].
by_mix_test_() ->
[
?BASIC(by_mix),
?ERROR(by_mix)
].
happy hackin'