Erlangでinject
新人さんにinject廚がいるみたいなのだが、以前の僕なら、それfoldlで(ryなんて言っていましたが、Erlangでinjectを作ってみた。
リファレンスマニュアル見て、素直に書いてみた。
erlang taka$ cat inject.erl -module(inject). -export([inject/2,inject/3]). %% 引き数2,3のinjectを公開 inject( F , [ H | [S | T ]] ) -> inject(F , F(H,S) , T) . %% 初期値が無い時の定義 inject( _ , N , [] ) -> N ; inject( F , N , [ H | T ] ) -> inject( F , F(N,H) ,T). erlang taka$ erl Erlang (BEAM) emulator version 5.5.4 [source] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.5.4 (abort with ^G) 1> c(inject). {ok,inject} 2> inject:inject(fun(X,Y) -> X + Y end , 0 , [1,2,3]). %% fun〜endはλ式 6 3> inject:inject(fun(X,Y) -> X + Y end , [1,2,3]). 6
しかし、Haskellというかghcはエラーメッセージがわかりにくい処理系だったけど、Erlangもわかりにくいなぁ。以下、ちとハマった部分。
erlang taka$ cat inject.erl -module(inject). -export([inject/2,inject/3]). inject( F , [ H | [S | T ]] ) -> inject(F , F(H,S) , T) . inject( _ , n , [] ) -> n ; inject( F , n , [ H | T ] ) -> inject( F , F(n,H) ,T). erlang taka$ erl Erlang (BEAM) emulator version 5.5.4 [source] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.5.4 (abort with ^G) 1> c(inject). {ok,inject} 2> inject:inject(fun(X,Y) -> X + Y end , 0 , [1,2,3]). =ERROR REPORT==== 2-May-2007::11:13:37 === Error in process <0.31.0> with exit value: {function_clause,[{inject,inject,[#Fun<erl_eval.12.24269688>,0,[1,2,3]]},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]} ** exited: {function_clause,[{inject,inject, [#Fun<erl_eval.12.24269688>,0,[1,2,3]]}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_loop,3}]} ** 3> User switch command --> q
上のコードでは、変数名としてNとしなきゃ行けない部分に間違って小文字のnを使ってしまっているために、たぶん、erlangがアトムのnと勘違いして、パターンマッチで合致する関数がないためエラーをはいているんだと思うんだけど、そんなの微塵にも感じさせない素晴らしきメッセージ。