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と勘違いして、パターンマッチで合致する関数がないためエラーをはいているんだと思うんだけど、そんなの微塵にも感じさせない素晴らしきメッセージ。