erlang #2 gen_serverで素数リストを求める

erlang #1 素数リストを求めるでつくったサーバを"Erlang World gen_server"を参考にしてgen_server化してみる。


init()の使い方がイマイチわからないまま。

# cat gprime.erl

-module(gprime).
-behaviour(gen_server).
-export([start/0]).
-export([get/1, check/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).
-compile(export_all).


start() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE,args,[]).

init(_Args) -> 
            Checked = 2,
            PrimeList =	[2],
    {ok, {Checked, PrimeList}}.

get(N) ->
    gen_server:call(?MODULE, {getlist, N}).
check(N) ->
    gen_server:call(?MODULE, {checkprime, N}).

handle_call({getlist, N}, _From, {Checked, PrimeList}) ->
    Ret = getl(N, Checked, PrimeList),
    {reply,
     Ret,
     {max(Checked, N), largeList(Ret, PrimeList)}
    };
handle_call({checkprime, N}, _From, {Checked, PrimeList}) ->
    Ret = getl(N, Checked, PrimeList),
    {reply,
     (lists:last(Ret) =:= N),
     {max(Checked, N), largeList(Ret, PrimeList)}
    }.

handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.

%% Nまでの素数リストを返す                                                                   
getl(1, _, _) -> [];
getl(N, Checked, PrimeList) ->
             if
                N =< Checked -> %% すでに求めた素数リストPrimeListから返す                   
                        lists:filter(fun(X) -> X =< N end, PrimeList);
                true -> %% すでに求めた素数リストに、Nまでの整数リストを追加                 
                     prime(trunc(math:sqrt(N)), [], PrimeList ++ lists:seq(Checked,N))
        end.

%% prime(Max:最大実行回数、P:素数リスト、[H|T]:2からNまでの整数のリスト)                     
prime(Max, P, [H|T]) -> 
        if
          H > Max -> 
                P ++ [H|T];
          true -> 
               prime(Max, P ++ [H],lists:filter(fun(X) -> (X rem H) =/= 0 end,  T))
         end.

largeList(L1, L2) ->
    if
      	(length(L1) < length(L2)) -> L2;
        true -> L2
    end.

実行方法は以下。

# erl
Erlang R16B02 (erts-5.10.3) [source] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V5.10.3  (abort with ^G)
1> gprime:start().
{ok,<0.34.0>}
2> gprime:get(10).
[2,3,5,7]
3> gprime:get(100).
[2,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,
 49,51,53,55,57,59,61,63,65|...]
4>